John Karatka / mbed

Fork of mbed-dev by mbed official

Committer:
AnnaBridge
Date:
Thu Jul 06 15:42:05 2017 +0100
Revision:
168:9672193075cf
Parent:
161:2cc1468da177
This updates the lib to the mbed lib v 146

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /**
<> 144:ef7eb2e8f9f7 2 ******************************************************************************
<> 144:ef7eb2e8f9f7 3 * @file stm32f7xx_ll_sdmmc.c
<> 144:ef7eb2e8f9f7 4 * @author MCD Application Team
AnnaBridge 168:9672193075cf 5 * @version V1.2.2
AnnaBridge 168:9672193075cf 6 * @date 14-April-2017
<> 144:ef7eb2e8f9f7 7 * @brief SDMMC Low Layer HAL module driver.
<> 144:ef7eb2e8f9f7 8 *
<> 144:ef7eb2e8f9f7 9 * This file provides firmware functions to manage the following
<> 144:ef7eb2e8f9f7 10 * functionalities of the SDMMC peripheral:
<> 144:ef7eb2e8f9f7 11 * + Initialization/de-initialization functions
<> 144:ef7eb2e8f9f7 12 * + I/O operation functions
<> 144:ef7eb2e8f9f7 13 * + Peripheral Control functions
<> 144:ef7eb2e8f9f7 14 * + Peripheral State functions
<> 144:ef7eb2e8f9f7 15 *
<> 144:ef7eb2e8f9f7 16 @verbatim
<> 144:ef7eb2e8f9f7 17 ==============================================================================
<> 144:ef7eb2e8f9f7 18 ##### SDMMC peripheral features #####
<> 144:ef7eb2e8f9f7 19 ==============================================================================
<> 144:ef7eb2e8f9f7 20 [..] The SD/SDMMC MMC card host interface (SDMMC) provides an interface between the APB2
<> 144:ef7eb2e8f9f7 21 peripheral bus and MultiMedia cards (MMCs), SD memory cards, SDMMC cards and CE-ATA
<> 144:ef7eb2e8f9f7 22 devices.
<> 144:ef7eb2e8f9f7 23
<> 144:ef7eb2e8f9f7 24 [..] The SDMMC features include the following:
<> 144:ef7eb2e8f9f7 25 (+) Full compliance with MultiMedia Card System Specification Version 4.2. Card support
<> 144:ef7eb2e8f9f7 26 for three different databus modes: 1-bit (default), 4-bit and 8-bit
<> 144:ef7eb2e8f9f7 27 (+) Full compatibility with previous versions of MultiMedia Cards (forward compatibility)
<> 144:ef7eb2e8f9f7 28 (+) Full compliance with SD Memory Card Specifications Version 2.0
<> 144:ef7eb2e8f9f7 29 (+) Full compliance with SD I/O Card Specification Version 2.0: card support for two
<> 144:ef7eb2e8f9f7 30 different data bus modes: 1-bit (default) and 4-bit
<> 144:ef7eb2e8f9f7 31 (+) Full support of the CE-ATA features (full compliance with CE-ATA digital protocol
<> 144:ef7eb2e8f9f7 32 Rev1.1)
<> 144:ef7eb2e8f9f7 33 (+) Data transfer up to 48 MHz for the 8 bit mode
<> 144:ef7eb2e8f9f7 34 (+) Data and command output enable signals to control external bidirectional drivers.
<> 144:ef7eb2e8f9f7 35
<> 144:ef7eb2e8f9f7 36
<> 144:ef7eb2e8f9f7 37 ##### How to use this driver #####
<> 144:ef7eb2e8f9f7 38 ==============================================================================
<> 144:ef7eb2e8f9f7 39 [..]
<> 144:ef7eb2e8f9f7 40 This driver is a considered as a driver of service for external devices drivers
<> 144:ef7eb2e8f9f7 41 that interfaces with the SDMMC peripheral.
<> 144:ef7eb2e8f9f7 42 According to the device used (SD card/ MMC card / SDMMC card ...), a set of APIs
<> 144:ef7eb2e8f9f7 43 is used in the device's driver to perform SDMMC operations and functionalities.
<> 144:ef7eb2e8f9f7 44
<> 144:ef7eb2e8f9f7 45 This driver is almost transparent for the final user, it is only used to implement other
<> 144:ef7eb2e8f9f7 46 functionalities of the external device.
<> 144:ef7eb2e8f9f7 47
<> 144:ef7eb2e8f9f7 48 [..]
<> 144:ef7eb2e8f9f7 49 (+) The SDMMC clock (SDMMCCLK = 48 MHz) is coming from a specific output of PLL
<> 144:ef7eb2e8f9f7 50 (PLL48CLK). Before start working with SDMMC peripheral make sure that the
<> 144:ef7eb2e8f9f7 51 PLL is well configured.
<> 144:ef7eb2e8f9f7 52 The SDMMC peripheral uses two clock signals:
<> 144:ef7eb2e8f9f7 53 (++) SDMMC adapter clock (SDMMCCLK = 48 MHz)
<> 144:ef7eb2e8f9f7 54 (++) APB2 bus clock (PCLK2)
<> 144:ef7eb2e8f9f7 55
<> 144:ef7eb2e8f9f7 56 -@@- PCLK2 and SDMMC_CK clock frequencies must respect the following condition:
<> 144:ef7eb2e8f9f7 57 Frequency(PCLK2) >= (3 / 8 x Frequency(SDMMC_CK))
<> 144:ef7eb2e8f9f7 58
<> 144:ef7eb2e8f9f7 59 (+) Enable/Disable peripheral clock using RCC peripheral macros related to SDMMC
<> 144:ef7eb2e8f9f7 60 peripheral.
<> 144:ef7eb2e8f9f7 61
<> 144:ef7eb2e8f9f7 62 (+) Enable the Power ON State using the SDMMC_PowerState_ON(SDMMCx)
<> 144:ef7eb2e8f9f7 63 function and disable it using the function SDMMC_PowerState_OFF(SDMMCx).
<> 144:ef7eb2e8f9f7 64
<> 144:ef7eb2e8f9f7 65 (+) Enable/Disable the clock using the __SDMMC_ENABLE()/__SDMMC_DISABLE() macros.
<> 144:ef7eb2e8f9f7 66
<> 144:ef7eb2e8f9f7 67 (+) Enable/Disable the peripheral interrupts using the macros __SDMMC_ENABLE_IT(hSDMMC, IT)
<> 144:ef7eb2e8f9f7 68 and __SDMMC_DISABLE_IT(hSDMMC, IT) if you need to use interrupt mode.
<> 144:ef7eb2e8f9f7 69
<> 144:ef7eb2e8f9f7 70 (+) When using the DMA mode
<> 144:ef7eb2e8f9f7 71 (++) Configure the DMA in the MSP layer of the external device
<> 144:ef7eb2e8f9f7 72 (++) Active the needed channel Request
<> 144:ef7eb2e8f9f7 73 (++) Enable the DMA using __SDMMC_DMA_ENABLE() macro or Disable it using the macro
<> 144:ef7eb2e8f9f7 74 __SDMMC_DMA_DISABLE().
<> 144:ef7eb2e8f9f7 75
<> 144:ef7eb2e8f9f7 76 (+) To control the CPSM (Command Path State Machine) and send
<> 144:ef7eb2e8f9f7 77 commands to the card use the SDMMC_SendCommand(SDMMCx),
<> 144:ef7eb2e8f9f7 78 SDMMC_GetCommandResponse() and SDMMC_GetResponse() functions. First, user has
<> 144:ef7eb2e8f9f7 79 to fill the command structure (pointer to SDMMC_CmdInitTypeDef) according
<> 144:ef7eb2e8f9f7 80 to the selected command to be sent.
<> 144:ef7eb2e8f9f7 81 The parameters that should be filled are:
<> 144:ef7eb2e8f9f7 82 (++) Command Argument
<> 144:ef7eb2e8f9f7 83 (++) Command Index
<> 144:ef7eb2e8f9f7 84 (++) Command Response type
<> 144:ef7eb2e8f9f7 85 (++) Command Wait
<> 144:ef7eb2e8f9f7 86 (++) CPSM Status (Enable or Disable).
<> 144:ef7eb2e8f9f7 87
<> 144:ef7eb2e8f9f7 88 -@@- To check if the command is well received, read the SDMMC_CMDRESP
<> 144:ef7eb2e8f9f7 89 register using the SDMMC_GetCommandResponse().
<> 144:ef7eb2e8f9f7 90 The SDMMC responses registers (SDMMC_RESP1 to SDMMC_RESP2), use the
<> 144:ef7eb2e8f9f7 91 SDMMC_GetResponse() function.
<> 144:ef7eb2e8f9f7 92
<> 144:ef7eb2e8f9f7 93 (+) To control the DPSM (Data Path State Machine) and send/receive
<> 144:ef7eb2e8f9f7 94 data to/from the card use the SDMMC_DataConfig(), SDMMC_GetDataCounter(),
<> 161:2cc1468da177 95 SDMMC_ReadFIFO(), SDMMC_WriteFIFO() and SDMMC_GetFIFOCount() functions.
<> 144:ef7eb2e8f9f7 96
<> 144:ef7eb2e8f9f7 97 *** Read Operations ***
<> 144:ef7eb2e8f9f7 98 =======================
<> 144:ef7eb2e8f9f7 99 [..]
<> 144:ef7eb2e8f9f7 100 (#) First, user has to fill the data structure (pointer to
<> 144:ef7eb2e8f9f7 101 SDMMC_DataInitTypeDef) according to the selected data type to be received.
<> 144:ef7eb2e8f9f7 102 The parameters that should be filled are:
<> 144:ef7eb2e8f9f7 103 (++) Data TimeOut
<> 144:ef7eb2e8f9f7 104 (++) Data Length
<> 144:ef7eb2e8f9f7 105 (++) Data Block size
<> 144:ef7eb2e8f9f7 106 (++) Data Transfer direction: should be from card (To SDMMC)
<> 144:ef7eb2e8f9f7 107 (++) Data Transfer mode
<> 144:ef7eb2e8f9f7 108 (++) DPSM Status (Enable or Disable)
<> 144:ef7eb2e8f9f7 109
<> 144:ef7eb2e8f9f7 110 (#) Configure the SDMMC resources to receive the data from the card
<> 144:ef7eb2e8f9f7 111 according to selected transfer mode (Refer to Step 8, 9 and 10).
<> 144:ef7eb2e8f9f7 112
<> 144:ef7eb2e8f9f7 113 (#) Send the selected Read command (refer to step 11).
<> 144:ef7eb2e8f9f7 114
<> 144:ef7eb2e8f9f7 115 (#) Use the SDMMC flags/interrupts to check the transfer status.
<> 144:ef7eb2e8f9f7 116
<> 144:ef7eb2e8f9f7 117 *** Write Operations ***
<> 144:ef7eb2e8f9f7 118 ========================
<> 144:ef7eb2e8f9f7 119 [..]
<> 144:ef7eb2e8f9f7 120 (#) First, user has to fill the data structure (pointer to
<> 144:ef7eb2e8f9f7 121 SDMMC_DataInitTypeDef) according to the selected data type to be received.
<> 144:ef7eb2e8f9f7 122 The parameters that should be filled are:
<> 144:ef7eb2e8f9f7 123 (++) Data TimeOut
<> 144:ef7eb2e8f9f7 124 (++) Data Length
<> 144:ef7eb2e8f9f7 125 (++) Data Block size
<> 144:ef7eb2e8f9f7 126 (++) Data Transfer direction: should be to card (To CARD)
<> 144:ef7eb2e8f9f7 127 (++) Data Transfer mode
<> 144:ef7eb2e8f9f7 128 (++) DPSM Status (Enable or Disable)
<> 144:ef7eb2e8f9f7 129
<> 144:ef7eb2e8f9f7 130 (#) Configure the SDMMC resources to send the data to the card according to
<> 144:ef7eb2e8f9f7 131 selected transfer mode.
<> 144:ef7eb2e8f9f7 132
<> 144:ef7eb2e8f9f7 133 (#) Send the selected Write command.
<> 144:ef7eb2e8f9f7 134
<> 144:ef7eb2e8f9f7 135 (#) Use the SDMMC flags/interrupts to check the transfer status.
<> 161:2cc1468da177 136
<> 161:2cc1468da177 137 *** Command management operations ***
<> 161:2cc1468da177 138 =====================================
<> 161:2cc1468da177 139 [..]
<> 161:2cc1468da177 140 (#) The commands used for Read/Write//Erase operations are managed in
<> 161:2cc1468da177 141 separate functions.
<> 161:2cc1468da177 142 Each function allows to send the needed command with the related argument,
<> 161:2cc1468da177 143 then check the response.
<> 161:2cc1468da177 144 By the same approach, you could implement a command and check the response.
<> 144:ef7eb2e8f9f7 145
<> 144:ef7eb2e8f9f7 146 @endverbatim
<> 144:ef7eb2e8f9f7 147 ******************************************************************************
<> 144:ef7eb2e8f9f7 148 * @attention
<> 144:ef7eb2e8f9f7 149 *
AnnaBridge 168:9672193075cf 150 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
<> 144:ef7eb2e8f9f7 151 *
<> 144:ef7eb2e8f9f7 152 * Redistribution and use in source and binary forms, with or without modification,
<> 144:ef7eb2e8f9f7 153 * are permitted provided that the following conditions are met:
<> 144:ef7eb2e8f9f7 154 * 1. Redistributions of source code must retain the above copyright notice,
<> 144:ef7eb2e8f9f7 155 * this list of conditions and the following disclaimer.
<> 144:ef7eb2e8f9f7 156 * 2. Redistributions in binary form must reproduce the above copyright notice,
<> 144:ef7eb2e8f9f7 157 * this list of conditions and the following disclaimer in the documentation
<> 144:ef7eb2e8f9f7 158 * and/or other materials provided with the distribution.
<> 144:ef7eb2e8f9f7 159 * 3. Neither the name of STMicroelectronics nor the names of its contributors
<> 144:ef7eb2e8f9f7 160 * may be used to endorse or promote products derived from this software
<> 144:ef7eb2e8f9f7 161 * without specific prior written permission.
<> 144:ef7eb2e8f9f7 162 *
<> 144:ef7eb2e8f9f7 163 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
<> 144:ef7eb2e8f9f7 164 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
<> 144:ef7eb2e8f9f7 165 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 144:ef7eb2e8f9f7 166 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
<> 144:ef7eb2e8f9f7 167 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
<> 144:ef7eb2e8f9f7 168 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
<> 144:ef7eb2e8f9f7 169 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
<> 144:ef7eb2e8f9f7 170 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
<> 144:ef7eb2e8f9f7 171 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
<> 144:ef7eb2e8f9f7 172 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 144:ef7eb2e8f9f7 173 *
<> 144:ef7eb2e8f9f7 174 ******************************************************************************
<> 144:ef7eb2e8f9f7 175 */
<> 144:ef7eb2e8f9f7 176
<> 144:ef7eb2e8f9f7 177 /* Includes ------------------------------------------------------------------*/
<> 144:ef7eb2e8f9f7 178 #include "stm32f7xx_hal.h"
<> 144:ef7eb2e8f9f7 179
<> 144:ef7eb2e8f9f7 180 /** @addtogroup STM32F7xx_HAL_Driver
<> 144:ef7eb2e8f9f7 181 * @{
<> 144:ef7eb2e8f9f7 182 */
<> 144:ef7eb2e8f9f7 183
<> 144:ef7eb2e8f9f7 184 /** @defgroup SDMMC_LL SDMMC Low Layer
<> 144:ef7eb2e8f9f7 185 * @brief Low layer module for SD
<> 144:ef7eb2e8f9f7 186 * @{
<> 144:ef7eb2e8f9f7 187 */
<> 144:ef7eb2e8f9f7 188
<> 144:ef7eb2e8f9f7 189 #if defined (HAL_SD_MODULE_ENABLED) || defined(HAL_MMC_MODULE_ENABLED)
<> 144:ef7eb2e8f9f7 190
<> 144:ef7eb2e8f9f7 191 /* Private typedef -----------------------------------------------------------*/
<> 144:ef7eb2e8f9f7 192 /* Private define ------------------------------------------------------------*/
<> 144:ef7eb2e8f9f7 193 /* Private macro -------------------------------------------------------------*/
<> 144:ef7eb2e8f9f7 194 /* Private variables ---------------------------------------------------------*/
<> 144:ef7eb2e8f9f7 195 /* Private function prototypes -----------------------------------------------*/
<> 161:2cc1468da177 196 static uint32_t SDMMC_GetCmdError(SDMMC_TypeDef *SDMMCx);
<> 161:2cc1468da177 197 static uint32_t SDMMC_GetCmdResp1(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint32_t Timeout);
<> 161:2cc1468da177 198 static uint32_t SDMMC_GetCmdResp2(SDMMC_TypeDef *SDMMCx);
<> 161:2cc1468da177 199 static uint32_t SDMMC_GetCmdResp3(SDMMC_TypeDef *SDMMCx);
<> 161:2cc1468da177 200 static uint32_t SDMMC_GetCmdResp7(SDMMC_TypeDef *SDMMCx);
<> 161:2cc1468da177 201 static uint32_t SDMMC_GetCmdResp6(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint16_t *pRCA);
<> 161:2cc1468da177 202
<> 144:ef7eb2e8f9f7 203 /* Exported functions --------------------------------------------------------*/
<> 144:ef7eb2e8f9f7 204
<> 144:ef7eb2e8f9f7 205 /** @defgroup SDMMC_LL_Exported_Functions SDMMC Low Layer Exported Functions
<> 144:ef7eb2e8f9f7 206 * @{
<> 144:ef7eb2e8f9f7 207 */
<> 144:ef7eb2e8f9f7 208
<> 144:ef7eb2e8f9f7 209 /** @defgroup HAL_SDMMC_LL_Group1 Initialization de-initialization functions
<> 144:ef7eb2e8f9f7 210 * @brief Initialization and Configuration functions
<> 144:ef7eb2e8f9f7 211 *
<> 144:ef7eb2e8f9f7 212 @verbatim
<> 144:ef7eb2e8f9f7 213 ===============================================================================
<> 144:ef7eb2e8f9f7 214 ##### Initialization/de-initialization functions #####
<> 144:ef7eb2e8f9f7 215 ===============================================================================
<> 144:ef7eb2e8f9f7 216 [..] This section provides functions allowing to:
<> 144:ef7eb2e8f9f7 217
<> 144:ef7eb2e8f9f7 218 @endverbatim
<> 144:ef7eb2e8f9f7 219 * @{
<> 144:ef7eb2e8f9f7 220 */
<> 144:ef7eb2e8f9f7 221
<> 144:ef7eb2e8f9f7 222 /**
<> 144:ef7eb2e8f9f7 223 * @brief Initializes the SDMMC according to the specified
<> 144:ef7eb2e8f9f7 224 * parameters in the SDMMC_InitTypeDef and create the associated handle.
<> 144:ef7eb2e8f9f7 225 * @param SDMMCx: Pointer to SDMMC register base
<> 144:ef7eb2e8f9f7 226 * @param Init: SDMMC initialization structure
<> 144:ef7eb2e8f9f7 227 * @retval HAL status
<> 144:ef7eb2e8f9f7 228 */
<> 144:ef7eb2e8f9f7 229 HAL_StatusTypeDef SDMMC_Init(SDMMC_TypeDef *SDMMCx, SDMMC_InitTypeDef Init)
<> 144:ef7eb2e8f9f7 230 {
<> 144:ef7eb2e8f9f7 231 uint32_t tmpreg = 0;
<> 144:ef7eb2e8f9f7 232
<> 144:ef7eb2e8f9f7 233 /* Check the parameters */
<> 144:ef7eb2e8f9f7 234 assert_param(IS_SDMMC_ALL_INSTANCE(SDMMCx));
<> 144:ef7eb2e8f9f7 235 assert_param(IS_SDMMC_CLOCK_EDGE(Init.ClockEdge));
<> 144:ef7eb2e8f9f7 236 assert_param(IS_SDMMC_CLOCK_BYPASS(Init.ClockBypass));
<> 144:ef7eb2e8f9f7 237 assert_param(IS_SDMMC_CLOCK_POWER_SAVE(Init.ClockPowerSave));
<> 144:ef7eb2e8f9f7 238 assert_param(IS_SDMMC_BUS_WIDE(Init.BusWide));
<> 144:ef7eb2e8f9f7 239 assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(Init.HardwareFlowControl));
<> 144:ef7eb2e8f9f7 240 assert_param(IS_SDMMC_CLKDIV(Init.ClockDiv));
<> 144:ef7eb2e8f9f7 241
<> 144:ef7eb2e8f9f7 242 /* Set SDMMC configuration parameters */
<> 144:ef7eb2e8f9f7 243 tmpreg |= (Init.ClockEdge |\
<> 144:ef7eb2e8f9f7 244 Init.ClockBypass |\
<> 144:ef7eb2e8f9f7 245 Init.ClockPowerSave |\
<> 144:ef7eb2e8f9f7 246 Init.BusWide |\
<> 144:ef7eb2e8f9f7 247 Init.HardwareFlowControl |\
<> 144:ef7eb2e8f9f7 248 Init.ClockDiv
<> 144:ef7eb2e8f9f7 249 );
<> 144:ef7eb2e8f9f7 250
<> 144:ef7eb2e8f9f7 251 /* Write to SDMMC CLKCR */
<> 144:ef7eb2e8f9f7 252 MODIFY_REG(SDMMCx->CLKCR, CLKCR_CLEAR_MASK, tmpreg);
<> 144:ef7eb2e8f9f7 253
<> 144:ef7eb2e8f9f7 254 return HAL_OK;
<> 144:ef7eb2e8f9f7 255 }
<> 144:ef7eb2e8f9f7 256
<> 144:ef7eb2e8f9f7 257
<> 144:ef7eb2e8f9f7 258 /**
<> 144:ef7eb2e8f9f7 259 * @}
<> 144:ef7eb2e8f9f7 260 */
<> 144:ef7eb2e8f9f7 261
<> 144:ef7eb2e8f9f7 262 /** @defgroup HAL_SDMMC_LL_Group2 IO operation functions
<> 144:ef7eb2e8f9f7 263 * @brief Data transfers functions
<> 144:ef7eb2e8f9f7 264 *
<> 144:ef7eb2e8f9f7 265 @verbatim
<> 144:ef7eb2e8f9f7 266 ===============================================================================
<> 144:ef7eb2e8f9f7 267 ##### I/O operation functions #####
<> 144:ef7eb2e8f9f7 268 ===============================================================================
<> 144:ef7eb2e8f9f7 269 [..]
<> 144:ef7eb2e8f9f7 270 This subsection provides a set of functions allowing to manage the SDMMC data
<> 144:ef7eb2e8f9f7 271 transfers.
<> 144:ef7eb2e8f9f7 272
<> 144:ef7eb2e8f9f7 273 @endverbatim
<> 144:ef7eb2e8f9f7 274 * @{
<> 144:ef7eb2e8f9f7 275 */
<> 144:ef7eb2e8f9f7 276
<> 144:ef7eb2e8f9f7 277 /**
<> 144:ef7eb2e8f9f7 278 * @brief Read data (word) from Rx FIFO in blocking mode (polling)
<> 144:ef7eb2e8f9f7 279 * @param SDMMCx: Pointer to SDMMC register base
<> 144:ef7eb2e8f9f7 280 * @retval HAL status
<> 144:ef7eb2e8f9f7 281 */
<> 144:ef7eb2e8f9f7 282 uint32_t SDMMC_ReadFIFO(SDMMC_TypeDef *SDMMCx)
<> 144:ef7eb2e8f9f7 283 {
<> 144:ef7eb2e8f9f7 284 /* Read data from Rx FIFO */
<> 144:ef7eb2e8f9f7 285 return (SDMMCx->FIFO);
<> 144:ef7eb2e8f9f7 286 }
<> 144:ef7eb2e8f9f7 287
<> 144:ef7eb2e8f9f7 288 /**
<> 144:ef7eb2e8f9f7 289 * @brief Write data (word) to Tx FIFO in blocking mode (polling)
<> 144:ef7eb2e8f9f7 290 * @param SDMMCx: Pointer to SDMMC register base
<> 144:ef7eb2e8f9f7 291 * @param pWriteData: pointer to data to write
<> 144:ef7eb2e8f9f7 292 * @retval HAL status
<> 144:ef7eb2e8f9f7 293 */
<> 144:ef7eb2e8f9f7 294 HAL_StatusTypeDef SDMMC_WriteFIFO(SDMMC_TypeDef *SDMMCx, uint32_t *pWriteData)
<> 144:ef7eb2e8f9f7 295 {
<> 144:ef7eb2e8f9f7 296 /* Write data to FIFO */
<> 144:ef7eb2e8f9f7 297 SDMMCx->FIFO = *pWriteData;
<> 144:ef7eb2e8f9f7 298
<> 144:ef7eb2e8f9f7 299 return HAL_OK;
<> 144:ef7eb2e8f9f7 300 }
<> 144:ef7eb2e8f9f7 301
<> 144:ef7eb2e8f9f7 302 /**
<> 144:ef7eb2e8f9f7 303 * @}
<> 144:ef7eb2e8f9f7 304 */
<> 144:ef7eb2e8f9f7 305
<> 144:ef7eb2e8f9f7 306 /** @defgroup HAL_SDMMC_LL_Group3 Peripheral Control functions
<> 144:ef7eb2e8f9f7 307 * @brief management functions
<> 144:ef7eb2e8f9f7 308 *
<> 144:ef7eb2e8f9f7 309 @verbatim
<> 144:ef7eb2e8f9f7 310 ===============================================================================
<> 144:ef7eb2e8f9f7 311 ##### Peripheral Control functions #####
<> 144:ef7eb2e8f9f7 312 ===============================================================================
<> 144:ef7eb2e8f9f7 313 [..]
<> 144:ef7eb2e8f9f7 314 This subsection provides a set of functions allowing to control the SDMMC data
<> 144:ef7eb2e8f9f7 315 transfers.
<> 144:ef7eb2e8f9f7 316
<> 144:ef7eb2e8f9f7 317 @endverbatim
<> 144:ef7eb2e8f9f7 318 * @{
<> 144:ef7eb2e8f9f7 319 */
<> 144:ef7eb2e8f9f7 320
<> 144:ef7eb2e8f9f7 321 /**
<> 144:ef7eb2e8f9f7 322 * @brief Set SDMMC Power state to ON.
<> 144:ef7eb2e8f9f7 323 * @param SDMMCx: Pointer to SDMMC register base
<> 144:ef7eb2e8f9f7 324 * @retval HAL status
<> 144:ef7eb2e8f9f7 325 */
<> 144:ef7eb2e8f9f7 326 HAL_StatusTypeDef SDMMC_PowerState_ON(SDMMC_TypeDef *SDMMCx)
<> 144:ef7eb2e8f9f7 327 {
<> 144:ef7eb2e8f9f7 328 /* Set power state to ON */
<> 144:ef7eb2e8f9f7 329 SDMMCx->POWER = SDMMC_POWER_PWRCTRL;
<> 144:ef7eb2e8f9f7 330
<> 144:ef7eb2e8f9f7 331 return HAL_OK;
<> 144:ef7eb2e8f9f7 332 }
<> 144:ef7eb2e8f9f7 333
<> 144:ef7eb2e8f9f7 334 /**
<> 144:ef7eb2e8f9f7 335 * @brief Set SDMMC Power state to OFF.
<> 144:ef7eb2e8f9f7 336 * @param SDMMCx: Pointer to SDMMC register base
<> 144:ef7eb2e8f9f7 337 * @retval HAL status
<> 144:ef7eb2e8f9f7 338 */
<> 144:ef7eb2e8f9f7 339 HAL_StatusTypeDef SDMMC_PowerState_OFF(SDMMC_TypeDef *SDMMCx)
<> 144:ef7eb2e8f9f7 340 {
<> 144:ef7eb2e8f9f7 341 /* Set power state to OFF */
<> 144:ef7eb2e8f9f7 342 SDMMCx->POWER = (uint32_t)0x00000000;
<> 144:ef7eb2e8f9f7 343
<> 144:ef7eb2e8f9f7 344 return HAL_OK;
<> 144:ef7eb2e8f9f7 345 }
<> 144:ef7eb2e8f9f7 346
<> 144:ef7eb2e8f9f7 347 /**
<> 144:ef7eb2e8f9f7 348 * @brief Get SDMMC Power state.
<> 144:ef7eb2e8f9f7 349 * @param SDMMCx: Pointer to SDMMC register base
<> 144:ef7eb2e8f9f7 350 * @retval Power status of the controller. The returned value can be one of the
<> 144:ef7eb2e8f9f7 351 * following values:
<> 144:ef7eb2e8f9f7 352 * - 0x00: Power OFF
<> 144:ef7eb2e8f9f7 353 * - 0x02: Power UP
<> 144:ef7eb2e8f9f7 354 * - 0x03: Power ON
<> 144:ef7eb2e8f9f7 355 */
<> 144:ef7eb2e8f9f7 356 uint32_t SDMMC_GetPowerState(SDMMC_TypeDef *SDMMCx)
<> 144:ef7eb2e8f9f7 357 {
<> 144:ef7eb2e8f9f7 358 return (SDMMCx->POWER & SDMMC_POWER_PWRCTRL);
<> 144:ef7eb2e8f9f7 359 }
<> 144:ef7eb2e8f9f7 360
<> 144:ef7eb2e8f9f7 361 /**
<> 144:ef7eb2e8f9f7 362 * @brief Configure the SDMMC command path according to the specified parameters in
<> 144:ef7eb2e8f9f7 363 * SDMMC_CmdInitTypeDef structure and send the command
<> 144:ef7eb2e8f9f7 364 * @param SDMMCx: Pointer to SDMMC register base
<> 144:ef7eb2e8f9f7 365 * @param Command: pointer to a SDMMC_CmdInitTypeDef structure that contains
<> 144:ef7eb2e8f9f7 366 * the configuration information for the SDMMC command
<> 144:ef7eb2e8f9f7 367 * @retval HAL status
<> 144:ef7eb2e8f9f7 368 */
<> 144:ef7eb2e8f9f7 369 HAL_StatusTypeDef SDMMC_SendCommand(SDMMC_TypeDef *SDMMCx, SDMMC_CmdInitTypeDef *Command)
<> 144:ef7eb2e8f9f7 370 {
<> 144:ef7eb2e8f9f7 371 uint32_t tmpreg = 0;
<> 144:ef7eb2e8f9f7 372
<> 144:ef7eb2e8f9f7 373 /* Check the parameters */
<> 144:ef7eb2e8f9f7 374 assert_param(IS_SDMMC_CMD_INDEX(Command->CmdIndex));
<> 144:ef7eb2e8f9f7 375 assert_param(IS_SDMMC_RESPONSE(Command->Response));
<> 144:ef7eb2e8f9f7 376 assert_param(IS_SDMMC_WAIT(Command->WaitForInterrupt));
<> 144:ef7eb2e8f9f7 377 assert_param(IS_SDMMC_CPSM(Command->CPSM));
<> 144:ef7eb2e8f9f7 378
<> 144:ef7eb2e8f9f7 379 /* Set the SDMMC Argument value */
<> 144:ef7eb2e8f9f7 380 SDMMCx->ARG = Command->Argument;
<> 144:ef7eb2e8f9f7 381
<> 144:ef7eb2e8f9f7 382 /* Set SDMMC command parameters */
<> 144:ef7eb2e8f9f7 383 tmpreg |= (uint32_t)(Command->CmdIndex |\
<> 144:ef7eb2e8f9f7 384 Command->Response |\
<> 144:ef7eb2e8f9f7 385 Command->WaitForInterrupt |\
<> 144:ef7eb2e8f9f7 386 Command->CPSM);
<> 144:ef7eb2e8f9f7 387
<> 144:ef7eb2e8f9f7 388 /* Write to SDMMC CMD register */
<> 144:ef7eb2e8f9f7 389 MODIFY_REG(SDMMCx->CMD, CMD_CLEAR_MASK, tmpreg);
<> 144:ef7eb2e8f9f7 390
<> 144:ef7eb2e8f9f7 391 return HAL_OK;
<> 144:ef7eb2e8f9f7 392 }
<> 144:ef7eb2e8f9f7 393
<> 144:ef7eb2e8f9f7 394 /**
<> 144:ef7eb2e8f9f7 395 * @brief Return the command index of last command for which response received
<> 144:ef7eb2e8f9f7 396 * @param SDMMCx: Pointer to SDMMC register base
<> 144:ef7eb2e8f9f7 397 * @retval Command index of the last command response received
<> 144:ef7eb2e8f9f7 398 */
<> 144:ef7eb2e8f9f7 399 uint8_t SDMMC_GetCommandResponse(SDMMC_TypeDef *SDMMCx)
<> 144:ef7eb2e8f9f7 400 {
<> 144:ef7eb2e8f9f7 401 return (uint8_t)(SDMMCx->RESPCMD);
<> 144:ef7eb2e8f9f7 402 }
<> 144:ef7eb2e8f9f7 403
<> 144:ef7eb2e8f9f7 404
<> 144:ef7eb2e8f9f7 405 /**
<> 144:ef7eb2e8f9f7 406 * @brief Return the response received from the card for the last command
<> 144:ef7eb2e8f9f7 407 * @param SDMMCx: Pointer to SDMMC register base
<> 144:ef7eb2e8f9f7 408 * @param Response: Specifies the SDMMC response register.
<> 144:ef7eb2e8f9f7 409 * This parameter can be one of the following values:
<> 144:ef7eb2e8f9f7 410 * @arg SDMMC_RESP1: Response Register 1
<> 144:ef7eb2e8f9f7 411 * @arg SDMMC_RESP2: Response Register 2
<> 144:ef7eb2e8f9f7 412 * @arg SDMMC_RESP3: Response Register 3
<> 144:ef7eb2e8f9f7 413 * @arg SDMMC_RESP4: Response Register 4
<> 144:ef7eb2e8f9f7 414 * @retval The Corresponding response register value
<> 144:ef7eb2e8f9f7 415 */
<> 144:ef7eb2e8f9f7 416 uint32_t SDMMC_GetResponse(SDMMC_TypeDef *SDMMCx, uint32_t Response)
<> 144:ef7eb2e8f9f7 417 {
<> 144:ef7eb2e8f9f7 418 __IO uint32_t tmp = 0;
<> 144:ef7eb2e8f9f7 419
<> 144:ef7eb2e8f9f7 420 /* Check the parameters */
<> 144:ef7eb2e8f9f7 421 assert_param(IS_SDMMC_RESP(Response));
<> 144:ef7eb2e8f9f7 422
<> 144:ef7eb2e8f9f7 423 /* Get the response */
<> 144:ef7eb2e8f9f7 424 tmp = (uint32_t)&(SDMMCx->RESP1) + Response;
<> 144:ef7eb2e8f9f7 425
<> 144:ef7eb2e8f9f7 426 return (*(__IO uint32_t *) tmp);
<> 144:ef7eb2e8f9f7 427 }
<> 144:ef7eb2e8f9f7 428
<> 144:ef7eb2e8f9f7 429 /**
<> 144:ef7eb2e8f9f7 430 * @brief Configure the SDMMC data path according to the specified
<> 144:ef7eb2e8f9f7 431 * parameters in the SDMMC_DataInitTypeDef.
<> 144:ef7eb2e8f9f7 432 * @param SDMMCx: Pointer to SDMMC register base
<> 144:ef7eb2e8f9f7 433 * @param Data : pointer to a SDMMC_DataInitTypeDef structure
<> 144:ef7eb2e8f9f7 434 * that contains the configuration information for the SDMMC data.
<> 144:ef7eb2e8f9f7 435 * @retval HAL status
<> 144:ef7eb2e8f9f7 436 */
<> 161:2cc1468da177 437 HAL_StatusTypeDef SDMMC_ConfigData(SDMMC_TypeDef *SDMMCx, SDMMC_DataInitTypeDef* Data)
<> 144:ef7eb2e8f9f7 438 {
<> 144:ef7eb2e8f9f7 439 uint32_t tmpreg = 0;
<> 144:ef7eb2e8f9f7 440
<> 144:ef7eb2e8f9f7 441 /* Check the parameters */
<> 144:ef7eb2e8f9f7 442 assert_param(IS_SDMMC_DATA_LENGTH(Data->DataLength));
<> 144:ef7eb2e8f9f7 443 assert_param(IS_SDMMC_BLOCK_SIZE(Data->DataBlockSize));
<> 144:ef7eb2e8f9f7 444 assert_param(IS_SDMMC_TRANSFER_DIR(Data->TransferDir));
<> 144:ef7eb2e8f9f7 445 assert_param(IS_SDMMC_TRANSFER_MODE(Data->TransferMode));
<> 144:ef7eb2e8f9f7 446 assert_param(IS_SDMMC_DPSM(Data->DPSM));
<> 144:ef7eb2e8f9f7 447
<> 144:ef7eb2e8f9f7 448 /* Set the SDMMC Data TimeOut value */
<> 144:ef7eb2e8f9f7 449 SDMMCx->DTIMER = Data->DataTimeOut;
<> 144:ef7eb2e8f9f7 450
<> 144:ef7eb2e8f9f7 451 /* Set the SDMMC DataLength value */
<> 144:ef7eb2e8f9f7 452 SDMMCx->DLEN = Data->DataLength;
<> 144:ef7eb2e8f9f7 453
<> 144:ef7eb2e8f9f7 454 /* Set the SDMMC data configuration parameters */
<> 144:ef7eb2e8f9f7 455 tmpreg |= (uint32_t)(Data->DataBlockSize |\
<> 144:ef7eb2e8f9f7 456 Data->TransferDir |\
<> 144:ef7eb2e8f9f7 457 Data->TransferMode |\
<> 144:ef7eb2e8f9f7 458 Data->DPSM);
<> 144:ef7eb2e8f9f7 459
<> 144:ef7eb2e8f9f7 460 /* Write to SDMMC DCTRL */
<> 144:ef7eb2e8f9f7 461 MODIFY_REG(SDMMCx->DCTRL, DCTRL_CLEAR_MASK, tmpreg);
<> 144:ef7eb2e8f9f7 462
<> 144:ef7eb2e8f9f7 463 return HAL_OK;
<> 144:ef7eb2e8f9f7 464
<> 144:ef7eb2e8f9f7 465 }
<> 144:ef7eb2e8f9f7 466
<> 144:ef7eb2e8f9f7 467 /**
<> 144:ef7eb2e8f9f7 468 * @brief Returns number of remaining data bytes to be transferred.
<> 144:ef7eb2e8f9f7 469 * @param SDMMCx: Pointer to SDMMC register base
<> 144:ef7eb2e8f9f7 470 * @retval Number of remaining data bytes to be transferred
<> 144:ef7eb2e8f9f7 471 */
<> 144:ef7eb2e8f9f7 472 uint32_t SDMMC_GetDataCounter(SDMMC_TypeDef *SDMMCx)
<> 144:ef7eb2e8f9f7 473 {
<> 144:ef7eb2e8f9f7 474 return (SDMMCx->DCOUNT);
<> 144:ef7eb2e8f9f7 475 }
<> 144:ef7eb2e8f9f7 476
<> 144:ef7eb2e8f9f7 477 /**
<> 144:ef7eb2e8f9f7 478 * @brief Get the FIFO data
<> 144:ef7eb2e8f9f7 479 * @param SDMMCx: Pointer to SDMMC register base
<> 144:ef7eb2e8f9f7 480 * @retval Data received
<> 144:ef7eb2e8f9f7 481 */
<> 144:ef7eb2e8f9f7 482 uint32_t SDMMC_GetFIFOCount(SDMMC_TypeDef *SDMMCx)
<> 144:ef7eb2e8f9f7 483 {
<> 144:ef7eb2e8f9f7 484 return (SDMMCx->FIFO);
<> 144:ef7eb2e8f9f7 485 }
<> 144:ef7eb2e8f9f7 486
<> 144:ef7eb2e8f9f7 487 /**
<> 144:ef7eb2e8f9f7 488 * @brief Sets one of the two options of inserting read wait interval.
<> 144:ef7eb2e8f9f7 489 * @param SDMMCx: Pointer to SDMMC register base
<> 144:ef7eb2e8f9f7 490 * @param SDMMC_ReadWaitMode: SDMMC Read Wait operation mode.
<> 144:ef7eb2e8f9f7 491 * This parameter can be:
<> 144:ef7eb2e8f9f7 492 * @arg SDMMC_READ_WAIT_MODE_CLK: Read Wait control by stopping SDMMCCLK
<> 144:ef7eb2e8f9f7 493 * @arg SDMMC_READ_WAIT_MODE_DATA2: Read Wait control using SDMMC_DATA2
<> 144:ef7eb2e8f9f7 494 * @retval None
<> 144:ef7eb2e8f9f7 495 */
<> 144:ef7eb2e8f9f7 496 HAL_StatusTypeDef SDMMC_SetSDMMCReadWaitMode(SDMMC_TypeDef *SDMMCx, uint32_t SDMMC_ReadWaitMode)
<> 144:ef7eb2e8f9f7 497 {
<> 144:ef7eb2e8f9f7 498 /* Check the parameters */
<> 144:ef7eb2e8f9f7 499 assert_param(IS_SDMMC_READWAIT_MODE(SDMMC_ReadWaitMode));
<> 144:ef7eb2e8f9f7 500
<> 144:ef7eb2e8f9f7 501 /* Set SDMMC read wait mode */
<> 144:ef7eb2e8f9f7 502 MODIFY_REG(SDMMCx->DCTRL, SDMMC_DCTRL_RWMOD, SDMMC_ReadWaitMode);
<> 144:ef7eb2e8f9f7 503
<> 144:ef7eb2e8f9f7 504 return HAL_OK;
<> 144:ef7eb2e8f9f7 505 }
<> 144:ef7eb2e8f9f7 506
<> 144:ef7eb2e8f9f7 507 /**
<> 144:ef7eb2e8f9f7 508 * @}
<> 144:ef7eb2e8f9f7 509 */
<> 144:ef7eb2e8f9f7 510
<> 161:2cc1468da177 511
<> 161:2cc1468da177 512 /** @defgroup HAL_SDMMC_LL_Group4 Command management functions
<> 161:2cc1468da177 513 * @brief Data transfers functions
<> 161:2cc1468da177 514 *
<> 161:2cc1468da177 515 @verbatim
<> 161:2cc1468da177 516 ===============================================================================
<> 161:2cc1468da177 517 ##### Commands management functions #####
<> 161:2cc1468da177 518 ===============================================================================
<> 161:2cc1468da177 519 [..]
<> 161:2cc1468da177 520 This subsection provides a set of functions allowing to manage the needed commands.
<> 161:2cc1468da177 521
<> 161:2cc1468da177 522 @endverbatim
<> 161:2cc1468da177 523 * @{
<> 161:2cc1468da177 524 */
<> 161:2cc1468da177 525
<> 161:2cc1468da177 526 /**
<> 161:2cc1468da177 527 * @brief Send the Data Block Lenght command and check the response
<> 161:2cc1468da177 528 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 529 * @retval HAL status
<> 161:2cc1468da177 530 */
<> 161:2cc1468da177 531 uint32_t SDMMC_CmdBlockLength(SDMMC_TypeDef *SDMMCx, uint32_t BlockSize)
<> 161:2cc1468da177 532 {
<> 161:2cc1468da177 533 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 534 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 535
<> 161:2cc1468da177 536 /* Set Block Size for Card */
<> 161:2cc1468da177 537 sdmmc_cmdinit.Argument = (uint32_t)BlockSize;
<> 161:2cc1468da177 538 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_BLOCKLEN;
<> 161:2cc1468da177 539 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 540 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 541 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 542 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 543
<> 161:2cc1468da177 544 /* Check for error conditions */
<> 161:2cc1468da177 545 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SET_BLOCKLEN, SDMMC_CMDTIMEOUT);
<> 161:2cc1468da177 546
<> 161:2cc1468da177 547 return errorstate;
<> 161:2cc1468da177 548 }
<> 161:2cc1468da177 549
<> 161:2cc1468da177 550 /**
<> 161:2cc1468da177 551 * @brief Send the Read Single Block command and check the response
<> 161:2cc1468da177 552 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 553 * @retval HAL status
<> 161:2cc1468da177 554 */
<> 161:2cc1468da177 555 uint32_t SDMMC_CmdReadSingleBlock(SDMMC_TypeDef *SDMMCx, uint32_t ReadAdd)
<> 161:2cc1468da177 556 {
<> 161:2cc1468da177 557 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 558 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 559
<> 161:2cc1468da177 560 /* Set Block Size for Card */
<> 161:2cc1468da177 561 sdmmc_cmdinit.Argument = (uint32_t)ReadAdd;
<> 161:2cc1468da177 562 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_SINGLE_BLOCK;
<> 161:2cc1468da177 563 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 564 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 565 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 566 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 567
<> 161:2cc1468da177 568 /* Check for error conditions */
<> 161:2cc1468da177 569 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_READ_SINGLE_BLOCK, SDMMC_CMDTIMEOUT);
<> 161:2cc1468da177 570
<> 161:2cc1468da177 571 return errorstate;
<> 161:2cc1468da177 572 }
<> 161:2cc1468da177 573
<> 161:2cc1468da177 574 /**
<> 161:2cc1468da177 575 * @brief Send the Read Multi Block command and check the response
<> 161:2cc1468da177 576 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 577 * @retval HAL status
<> 161:2cc1468da177 578 */
<> 161:2cc1468da177 579 uint32_t SDMMC_CmdReadMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t ReadAdd)
<> 161:2cc1468da177 580 {
<> 161:2cc1468da177 581 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 582 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 583
<> 161:2cc1468da177 584 /* Set Block Size for Card */
<> 161:2cc1468da177 585 sdmmc_cmdinit.Argument = (uint32_t)ReadAdd;
<> 161:2cc1468da177 586 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_MULT_BLOCK;
<> 161:2cc1468da177 587 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 588 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 589 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 590 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 591
<> 161:2cc1468da177 592 /* Check for error conditions */
<> 161:2cc1468da177 593 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_READ_MULT_BLOCK, SDMMC_CMDTIMEOUT);
<> 161:2cc1468da177 594
<> 161:2cc1468da177 595 return errorstate;
<> 161:2cc1468da177 596 }
<> 161:2cc1468da177 597
<> 161:2cc1468da177 598 /**
<> 161:2cc1468da177 599 * @brief Send the Write Single Block command and check the response
<> 161:2cc1468da177 600 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 601 * @retval HAL status
<> 161:2cc1468da177 602 */
<> 161:2cc1468da177 603 uint32_t SDMMC_CmdWriteSingleBlock(SDMMC_TypeDef *SDMMCx, uint32_t WriteAdd)
<> 161:2cc1468da177 604 {
<> 161:2cc1468da177 605 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 606 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 607
<> 161:2cc1468da177 608 /* Set Block Size for Card */
<> 161:2cc1468da177 609 sdmmc_cmdinit.Argument = (uint32_t)WriteAdd;
<> 161:2cc1468da177 610 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_WRITE_SINGLE_BLOCK;
<> 161:2cc1468da177 611 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 612 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 613 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 614 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 615
<> 161:2cc1468da177 616 /* Check for error conditions */
<> 161:2cc1468da177 617 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_WRITE_SINGLE_BLOCK, SDMMC_CMDTIMEOUT);
<> 161:2cc1468da177 618
<> 161:2cc1468da177 619 return errorstate;
<> 161:2cc1468da177 620 }
<> 161:2cc1468da177 621
<> 161:2cc1468da177 622 /**
<> 161:2cc1468da177 623 * @brief Send the Write Multi Block command and check the response
<> 161:2cc1468da177 624 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 625 * @retval HAL status
<> 161:2cc1468da177 626 */
<> 161:2cc1468da177 627 uint32_t SDMMC_CmdWriteMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t WriteAdd)
<> 161:2cc1468da177 628 {
<> 161:2cc1468da177 629 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 630 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 631
<> 161:2cc1468da177 632 /* Set Block Size for Card */
<> 161:2cc1468da177 633 sdmmc_cmdinit.Argument = (uint32_t)WriteAdd;
<> 161:2cc1468da177 634 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_WRITE_MULT_BLOCK;
<> 161:2cc1468da177 635 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 636 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 637 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 638 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 639
<> 161:2cc1468da177 640 /* Check for error conditions */
<> 161:2cc1468da177 641 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_WRITE_MULT_BLOCK, SDMMC_CMDTIMEOUT);
<> 161:2cc1468da177 642
<> 161:2cc1468da177 643 return errorstate;
<> 161:2cc1468da177 644 }
<> 161:2cc1468da177 645
<> 161:2cc1468da177 646 /**
<> 161:2cc1468da177 647 * @brief Send the Start Address Erase command for SD and check the response
<> 161:2cc1468da177 648 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 649 * @retval HAL status
<> 161:2cc1468da177 650 */
<> 161:2cc1468da177 651 uint32_t SDMMC_CmdSDEraseStartAdd(SDMMC_TypeDef *SDMMCx, uint32_t StartAdd)
<> 161:2cc1468da177 652 {
<> 161:2cc1468da177 653 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 654 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 655
<> 161:2cc1468da177 656 /* Set Block Size for Card */
<> 161:2cc1468da177 657 sdmmc_cmdinit.Argument = (uint32_t)StartAdd;
<> 161:2cc1468da177 658 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_ERASE_GRP_START;
<> 161:2cc1468da177 659 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 660 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 661 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 662 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 663
<> 161:2cc1468da177 664 /* Check for error conditions */
<> 161:2cc1468da177 665 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_ERASE_GRP_START, SDMMC_CMDTIMEOUT);
<> 161:2cc1468da177 666
<> 161:2cc1468da177 667 return errorstate;
<> 161:2cc1468da177 668 }
<> 161:2cc1468da177 669
<> 161:2cc1468da177 670 /**
<> 161:2cc1468da177 671 * @brief Send the End Address Erase command for SD and check the response
<> 161:2cc1468da177 672 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 673 * @retval HAL status
<> 161:2cc1468da177 674 */
<> 161:2cc1468da177 675 uint32_t SDMMC_CmdSDEraseEndAdd(SDMMC_TypeDef *SDMMCx, uint32_t EndAdd)
<> 161:2cc1468da177 676 {
<> 161:2cc1468da177 677 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 678 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 679
<> 161:2cc1468da177 680 /* Set Block Size for Card */
<> 161:2cc1468da177 681 sdmmc_cmdinit.Argument = (uint32_t)EndAdd;
<> 161:2cc1468da177 682 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_ERASE_GRP_END;
<> 161:2cc1468da177 683 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 684 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 685 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 686 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 687
<> 161:2cc1468da177 688 /* Check for error conditions */
<> 161:2cc1468da177 689 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_ERASE_GRP_END, SDMMC_CMDTIMEOUT);
<> 161:2cc1468da177 690
<> 161:2cc1468da177 691 return errorstate;
<> 161:2cc1468da177 692 }
<> 161:2cc1468da177 693
<> 161:2cc1468da177 694 /**
<> 161:2cc1468da177 695 * @brief Send the Start Address Erase command and check the response
<> 161:2cc1468da177 696 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 697 * @retval HAL status
<> 161:2cc1468da177 698 */
<> 161:2cc1468da177 699 uint32_t SDMMC_CmdEraseStartAdd(SDMMC_TypeDef *SDMMCx, uint32_t StartAdd)
<> 161:2cc1468da177 700 {
<> 161:2cc1468da177 701 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 702 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 703
<> 161:2cc1468da177 704 /* Set Block Size for Card */
<> 161:2cc1468da177 705 sdmmc_cmdinit.Argument = (uint32_t)StartAdd;
<> 161:2cc1468da177 706 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE_GRP_START;
<> 161:2cc1468da177 707 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 708 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 709 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 710 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 711
<> 161:2cc1468da177 712 /* Check for error conditions */
<> 161:2cc1468da177 713 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE_GRP_START, SDMMC_CMDTIMEOUT);
<> 161:2cc1468da177 714
<> 161:2cc1468da177 715 return errorstate;
<> 161:2cc1468da177 716 }
<> 161:2cc1468da177 717
<> 161:2cc1468da177 718 /**
<> 161:2cc1468da177 719 * @brief Send the End Address Erase command and check the response
<> 161:2cc1468da177 720 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 721 * @retval HAL status
<> 161:2cc1468da177 722 */
<> 161:2cc1468da177 723 uint32_t SDMMC_CmdEraseEndAdd(SDMMC_TypeDef *SDMMCx, uint32_t EndAdd)
<> 161:2cc1468da177 724 {
<> 161:2cc1468da177 725 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 726 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 727
<> 161:2cc1468da177 728 /* Set Block Size for Card */
<> 161:2cc1468da177 729 sdmmc_cmdinit.Argument = (uint32_t)EndAdd;
<> 161:2cc1468da177 730 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE_GRP_END;
<> 161:2cc1468da177 731 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 732 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 733 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 734 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 735
<> 161:2cc1468da177 736 /* Check for error conditions */
<> 161:2cc1468da177 737 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE_GRP_END, SDMMC_CMDTIMEOUT);
<> 161:2cc1468da177 738
<> 161:2cc1468da177 739 return errorstate;
<> 161:2cc1468da177 740 }
<> 161:2cc1468da177 741
<> 161:2cc1468da177 742 /**
<> 161:2cc1468da177 743 * @brief Send the Erase command and check the response
<> 161:2cc1468da177 744 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 745 * @retval HAL status
<> 161:2cc1468da177 746 */
<> 161:2cc1468da177 747 uint32_t SDMMC_CmdErase(SDMMC_TypeDef *SDMMCx)
<> 161:2cc1468da177 748 {
<> 161:2cc1468da177 749 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 750 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 751
<> 161:2cc1468da177 752 /* Set Block Size for Card */
<> 161:2cc1468da177 753 sdmmc_cmdinit.Argument = 0;
<> 161:2cc1468da177 754 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE;
<> 161:2cc1468da177 755 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 756 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 757 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 758 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 759
<> 161:2cc1468da177 760 /* Check for error conditions */
<> 161:2cc1468da177 761 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE, SDMMC_MAXERASETIMEOUT);
<> 161:2cc1468da177 762
<> 161:2cc1468da177 763 return errorstate;
<> 161:2cc1468da177 764 }
<> 161:2cc1468da177 765
<> 161:2cc1468da177 766 /**
<> 161:2cc1468da177 767 * @brief Send the Stop Transfer command and check the response.
<> 161:2cc1468da177 768 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 769 * @retval HAL status
<> 161:2cc1468da177 770 */
<> 161:2cc1468da177 771 uint32_t SDMMC_CmdStopTransfer(SDMMC_TypeDef *SDMMCx)
<> 161:2cc1468da177 772 {
<> 161:2cc1468da177 773 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 774 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 775
<> 161:2cc1468da177 776 /* Send CMD12 STOP_TRANSMISSION */
<> 161:2cc1468da177 777 sdmmc_cmdinit.Argument = 0;
<> 161:2cc1468da177 778 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_STOP_TRANSMISSION;
<> 161:2cc1468da177 779 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 780 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 781 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 782 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 783
<> 161:2cc1468da177 784 /* Check for error conditions */
<> 161:2cc1468da177 785 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_STOP_TRANSMISSION, 100000000/*SDMMC_CMDTIMEOUT*/);
<> 161:2cc1468da177 786
<> 161:2cc1468da177 787 return errorstate;
<> 161:2cc1468da177 788 }
<> 161:2cc1468da177 789
<> 161:2cc1468da177 790 /**
<> 161:2cc1468da177 791 * @brief Send the Select Deselect command and check the response.
<> 161:2cc1468da177 792 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 793 * @param addr: Address of the card to be selected
<> 161:2cc1468da177 794 * @retval HAL status
<> 161:2cc1468da177 795 */
<> 161:2cc1468da177 796 uint32_t SDMMC_CmdSelDesel(SDMMC_TypeDef *SDMMCx, uint64_t Addr)
<> 161:2cc1468da177 797 {
<> 161:2cc1468da177 798 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 799 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 800
<> 161:2cc1468da177 801 /* Send CMD7 SDMMC_SEL_DESEL_CARD */
<> 161:2cc1468da177 802 sdmmc_cmdinit.Argument = (uint32_t)Addr;
<> 161:2cc1468da177 803 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEL_DESEL_CARD;
<> 161:2cc1468da177 804 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 805 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 806 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 807 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 808
<> 161:2cc1468da177 809 /* Check for error conditions */
<> 161:2cc1468da177 810 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SEL_DESEL_CARD, SDMMC_CMDTIMEOUT);
<> 161:2cc1468da177 811
<> 161:2cc1468da177 812 return errorstate;
<> 161:2cc1468da177 813 }
<> 161:2cc1468da177 814
<> 161:2cc1468da177 815 /**
<> 161:2cc1468da177 816 * @brief Send the Go Idle State command and check the response.
<> 161:2cc1468da177 817 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 818 * @retval HAL status
<> 161:2cc1468da177 819 */
<> 161:2cc1468da177 820 uint32_t SDMMC_CmdGoIdleState(SDMMC_TypeDef *SDMMCx)
<> 161:2cc1468da177 821 {
<> 161:2cc1468da177 822 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 823 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 824
<> 161:2cc1468da177 825 sdmmc_cmdinit.Argument = 0;
<> 161:2cc1468da177 826 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_GO_IDLE_STATE;
<> 161:2cc1468da177 827 sdmmc_cmdinit.Response = SDMMC_RESPONSE_NO;
<> 161:2cc1468da177 828 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 829 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 830 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 831
<> 161:2cc1468da177 832 /* Check for error conditions */
<> 161:2cc1468da177 833 errorstate = SDMMC_GetCmdError(SDMMCx);
<> 161:2cc1468da177 834
<> 161:2cc1468da177 835 return errorstate;
<> 161:2cc1468da177 836 }
<> 161:2cc1468da177 837
<> 161:2cc1468da177 838 /**
<> 161:2cc1468da177 839 * @brief Send the Operating Condition command and check the response.
<> 161:2cc1468da177 840 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 841 * @retval HAL status
<> 161:2cc1468da177 842 */
<> 161:2cc1468da177 843 uint32_t SDMMC_CmdOperCond(SDMMC_TypeDef *SDMMCx)
<> 161:2cc1468da177 844 {
<> 161:2cc1468da177 845 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 846 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 847
<> 161:2cc1468da177 848 /* Send CMD8 to verify SD card interface operating condition */
<> 161:2cc1468da177 849 /* Argument: - [31:12]: Reserved (shall be set to '0')
<> 161:2cc1468da177 850 - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
<> 161:2cc1468da177 851 - [7:0]: Check Pattern (recommended 0xAA) */
<> 161:2cc1468da177 852 /* CMD Response: R7 */
<> 161:2cc1468da177 853 sdmmc_cmdinit.Argument = SDMMC_CHECK_PATTERN;
<> 161:2cc1468da177 854 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SEND_EXT_CSD;
<> 161:2cc1468da177 855 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 856 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 857 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 858 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 859
<> 161:2cc1468da177 860 /* Check for error conditions */
<> 161:2cc1468da177 861 errorstate = SDMMC_GetCmdResp7(SDMMCx);
<> 161:2cc1468da177 862
<> 161:2cc1468da177 863 return errorstate;
<> 161:2cc1468da177 864 }
<> 161:2cc1468da177 865
<> 161:2cc1468da177 866 /**
<> 161:2cc1468da177 867 * @brief Send the Application command to verify that that the next command
<> 161:2cc1468da177 868 * is an application specific com-mand rather than a standard command
<> 161:2cc1468da177 869 * and check the response.
<> 161:2cc1468da177 870 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 871 * @retval HAL status
<> 161:2cc1468da177 872 */
<> 161:2cc1468da177 873 uint32_t SDMMC_CmdAppCommand(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
<> 161:2cc1468da177 874 {
<> 161:2cc1468da177 875 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 876 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 877
<> 161:2cc1468da177 878 sdmmc_cmdinit.Argument = (uint32_t)Argument;
<> 161:2cc1468da177 879 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_APP_CMD;
<> 161:2cc1468da177 880 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 881 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 882 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 883 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 884
<> 161:2cc1468da177 885 /* Check for error conditions */
<> 161:2cc1468da177 886 /* If there is a HAL_ERROR, it is a MMC card, else
<> 161:2cc1468da177 887 it is a SD card: SD card 2.0 (voltage range mismatch)
<> 161:2cc1468da177 888 or SD card 1.x */
<> 161:2cc1468da177 889 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_APP_CMD, SDMMC_CMDTIMEOUT);
<> 161:2cc1468da177 890
<> 161:2cc1468da177 891 return errorstate;
<> 161:2cc1468da177 892 }
<> 161:2cc1468da177 893
<> 161:2cc1468da177 894 /**
<> 161:2cc1468da177 895 * @brief Send the command asking the accessed card to send its operating
<> 161:2cc1468da177 896 * condition register (OCR)
<> 161:2cc1468da177 897 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 898 * @retval HAL status
<> 161:2cc1468da177 899 */
<> 161:2cc1468da177 900 uint32_t SDMMC_CmdAppOperCommand(SDMMC_TypeDef *SDMMCx, uint32_t SdType)
<> 161:2cc1468da177 901 {
<> 161:2cc1468da177 902 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 903 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 904
<> 161:2cc1468da177 905 sdmmc_cmdinit.Argument = SDMMC_VOLTAGE_WINDOW_SD | SdType;
<> 161:2cc1468da177 906 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_OP_COND;
<> 161:2cc1468da177 907 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 908 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 909 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 910 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 911
<> 161:2cc1468da177 912 /* Check for error conditions */
<> 161:2cc1468da177 913 errorstate = SDMMC_GetCmdResp3(SDMMCx);
<> 161:2cc1468da177 914
<> 161:2cc1468da177 915 return errorstate;
<> 161:2cc1468da177 916 }
<> 161:2cc1468da177 917
<> 161:2cc1468da177 918 /**
<> 161:2cc1468da177 919 * @brief Send the Bus Width command and check the response.
<> 161:2cc1468da177 920 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 921 * @retval HAL status
<> 161:2cc1468da177 922 */
<> 161:2cc1468da177 923 uint32_t SDMMC_CmdBusWidth(SDMMC_TypeDef *SDMMCx, uint32_t BusWidth)
<> 161:2cc1468da177 924 {
<> 161:2cc1468da177 925 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 926 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 927
<> 161:2cc1468da177 928 sdmmc_cmdinit.Argument = (uint32_t)BusWidth;
<> 161:2cc1468da177 929 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_APP_SD_SET_BUSWIDTH;
<> 161:2cc1468da177 930 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 931 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 932 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 933 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 934
<> 161:2cc1468da177 935 /* Check for error conditions */
<> 161:2cc1468da177 936 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_APP_SD_SET_BUSWIDTH, SDMMC_CMDTIMEOUT);
<> 161:2cc1468da177 937
<> 161:2cc1468da177 938 return errorstate;
<> 161:2cc1468da177 939 }
<> 161:2cc1468da177 940
<> 161:2cc1468da177 941 /**
<> 161:2cc1468da177 942 * @brief Send the Send SCR command and check the response.
<> 161:2cc1468da177 943 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 944 * @retval HAL status
<> 161:2cc1468da177 945 */
<> 161:2cc1468da177 946 uint32_t SDMMC_CmdSendSCR(SDMMC_TypeDef *SDMMCx)
<> 161:2cc1468da177 947 {
<> 161:2cc1468da177 948 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 949 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 950
<> 161:2cc1468da177 951 /* Send CMD51 SD_APP_SEND_SCR */
<> 161:2cc1468da177 952 sdmmc_cmdinit.Argument = 0;
<> 161:2cc1468da177 953 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_SEND_SCR;
<> 161:2cc1468da177 954 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 955 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 956 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 957 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 958
<> 161:2cc1468da177 959 /* Check for error conditions */
<> 161:2cc1468da177 960 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_APP_SEND_SCR, SDMMC_CMDTIMEOUT);
<> 161:2cc1468da177 961
<> 161:2cc1468da177 962 return errorstate;
<> 161:2cc1468da177 963 }
<> 161:2cc1468da177 964
<> 161:2cc1468da177 965 /**
<> 161:2cc1468da177 966 * @brief Send the Send CID command and check the response.
<> 161:2cc1468da177 967 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 968 * @retval HAL status
<> 161:2cc1468da177 969 */
<> 161:2cc1468da177 970 uint32_t SDMMC_CmdSendCID(SDMMC_TypeDef *SDMMCx)
<> 161:2cc1468da177 971 {
<> 161:2cc1468da177 972 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 973 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 974
<> 161:2cc1468da177 975 /* Send CMD2 ALL_SEND_CID */
<> 161:2cc1468da177 976 sdmmc_cmdinit.Argument = 0;
<> 161:2cc1468da177 977 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ALL_SEND_CID;
<> 161:2cc1468da177 978 sdmmc_cmdinit.Response = SDMMC_RESPONSE_LONG;
<> 161:2cc1468da177 979 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 980 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 981 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 982
<> 161:2cc1468da177 983 /* Check for error conditions */
<> 161:2cc1468da177 984 errorstate = SDMMC_GetCmdResp2(SDMMCx);
<> 161:2cc1468da177 985
<> 161:2cc1468da177 986 return errorstate;
<> 161:2cc1468da177 987 }
<> 161:2cc1468da177 988
<> 161:2cc1468da177 989 /**
<> 161:2cc1468da177 990 * @brief Send the Send CSD command and check the response.
<> 161:2cc1468da177 991 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 992 * @retval HAL status
<> 161:2cc1468da177 993 */
<> 161:2cc1468da177 994 uint32_t SDMMC_CmdSendCSD(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
<> 161:2cc1468da177 995 {
<> 161:2cc1468da177 996 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 997 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 998
<> 161:2cc1468da177 999 /* Send CMD9 SEND_CSD */
<> 161:2cc1468da177 1000 sdmmc_cmdinit.Argument = (uint32_t)Argument;
<> 161:2cc1468da177 1001 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_CSD;
<> 161:2cc1468da177 1002 sdmmc_cmdinit.Response = SDMMC_RESPONSE_LONG;
<> 161:2cc1468da177 1003 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 1004 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 1005 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 1006
<> 161:2cc1468da177 1007 /* Check for error conditions */
<> 161:2cc1468da177 1008 errorstate = SDMMC_GetCmdResp2(SDMMCx);
<> 161:2cc1468da177 1009
<> 161:2cc1468da177 1010 return errorstate;
<> 161:2cc1468da177 1011 }
<> 161:2cc1468da177 1012
<> 161:2cc1468da177 1013 /**
<> 161:2cc1468da177 1014 * @brief Send the Send CSD command and check the response.
<> 161:2cc1468da177 1015 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 1016 * @retval HAL status
<> 161:2cc1468da177 1017 */
<> 161:2cc1468da177 1018 uint32_t SDMMC_CmdSetRelAdd(SDMMC_TypeDef *SDMMCx, uint16_t *pRCA)
<> 161:2cc1468da177 1019 {
<> 161:2cc1468da177 1020 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 1021 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 1022
<> 161:2cc1468da177 1023 /* Send CMD3 SD_CMD_SET_REL_ADDR */
<> 161:2cc1468da177 1024 sdmmc_cmdinit.Argument = 0;
<> 161:2cc1468da177 1025 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR;
<> 161:2cc1468da177 1026 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 1027 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 1028 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 1029 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 1030
<> 161:2cc1468da177 1031 /* Check for error conditions */
<> 161:2cc1468da177 1032 errorstate = SDMMC_GetCmdResp6(SDMMCx, SDMMC_CMD_SET_REL_ADDR, pRCA);
<> 161:2cc1468da177 1033
<> 161:2cc1468da177 1034 return errorstate;
<> 161:2cc1468da177 1035 }
<> 161:2cc1468da177 1036
<> 161:2cc1468da177 1037 /**
<> 161:2cc1468da177 1038 * @brief Send the Status command and check the response.
<> 161:2cc1468da177 1039 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 1040 * @retval HAL status
<> 161:2cc1468da177 1041 */
<> 161:2cc1468da177 1042 uint32_t SDMMC_CmdSendStatus(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
<> 161:2cc1468da177 1043 {
<> 161:2cc1468da177 1044 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 1045 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 1046
<> 161:2cc1468da177 1047 sdmmc_cmdinit.Argument = (uint32_t)Argument;
<> 161:2cc1468da177 1048 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_STATUS;
<> 161:2cc1468da177 1049 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 1050 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 1051 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 1052 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 1053
<> 161:2cc1468da177 1054 /* Check for error conditions */
<> 161:2cc1468da177 1055 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SEND_STATUS, SDMMC_CMDTIMEOUT);
<> 161:2cc1468da177 1056
<> 161:2cc1468da177 1057 return errorstate;
<> 161:2cc1468da177 1058 }
<> 161:2cc1468da177 1059
<> 161:2cc1468da177 1060 /**
<> 161:2cc1468da177 1061 * @brief Send the Status register command and check the response.
<> 161:2cc1468da177 1062 * @param SDMMCx: Pointer to SDMMC register base
<> 161:2cc1468da177 1063 * @retval HAL status
<> 161:2cc1468da177 1064 */
<> 161:2cc1468da177 1065 uint32_t SDMMC_CmdStatusRegister(SDMMC_TypeDef *SDMMCx)
<> 161:2cc1468da177 1066 {
<> 161:2cc1468da177 1067 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 1068 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 1069
<> 161:2cc1468da177 1070 sdmmc_cmdinit.Argument = 0;
<> 161:2cc1468da177 1071 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_STATUS;
<> 161:2cc1468da177 1072 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 1073 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 1074 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 1075 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 1076
<> 161:2cc1468da177 1077 /* Check for error conditions */
<> 161:2cc1468da177 1078 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_APP_STATUS, SDMMC_CMDTIMEOUT);
<> 161:2cc1468da177 1079
<> 161:2cc1468da177 1080 return errorstate;
<> 161:2cc1468da177 1081 }
<> 161:2cc1468da177 1082
<> 161:2cc1468da177 1083 /**
<> 161:2cc1468da177 1084 * @brief Sends host capacity support information and activates the card's
<> 161:2cc1468da177 1085 * initialization process. Send SDMMC_CMD_SEND_OP_COND command
<> 161:2cc1468da177 1086 * @param SDIOx: Pointer to SDIO register base
<> 161:2cc1468da177 1087 * @parame Argument: Argument used for the command
<> 161:2cc1468da177 1088 * @retval HAL status
<> 161:2cc1468da177 1089 */
<> 161:2cc1468da177 1090 uint32_t SDMMC_CmdOpCondition(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
<> 161:2cc1468da177 1091 {
<> 161:2cc1468da177 1092 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 1093 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 1094
<> 161:2cc1468da177 1095 sdmmc_cmdinit.Argument = Argument;
<> 161:2cc1468da177 1096 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_OP_COND;
<> 161:2cc1468da177 1097 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 1098 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 1099 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 1100 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 1101
<> 161:2cc1468da177 1102 /* Check for error conditions */
<> 161:2cc1468da177 1103 errorstate = SDMMC_GetCmdResp3(SDMMCx);
<> 161:2cc1468da177 1104
<> 161:2cc1468da177 1105 return errorstate;
<> 161:2cc1468da177 1106 }
<> 161:2cc1468da177 1107
<> 161:2cc1468da177 1108 /**
<> 161:2cc1468da177 1109 * @brief Checks switchable function and switch card function. SDMMC_CMD_HS_SWITCH comand
<> 161:2cc1468da177 1110 * @param SDIOx: Pointer to SDIO register base
<> 161:2cc1468da177 1111 * @parame Argument: Argument used for the command
<> 161:2cc1468da177 1112 * @retval HAL status
<> 161:2cc1468da177 1113 */
<> 161:2cc1468da177 1114 uint32_t SDMMC_CmdSwitch(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
<> 161:2cc1468da177 1115 {
<> 161:2cc1468da177 1116 SDMMC_CmdInitTypeDef sdmmc_cmdinit;
<> 161:2cc1468da177 1117 uint32_t errorstate = SDMMC_ERROR_NONE;
<> 161:2cc1468da177 1118
<> 161:2cc1468da177 1119 sdmmc_cmdinit.Argument = Argument;
<> 161:2cc1468da177 1120 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SWITCH;
<> 161:2cc1468da177 1121 sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
<> 161:2cc1468da177 1122 sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
<> 161:2cc1468da177 1123 sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
<> 161:2cc1468da177 1124 SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
<> 161:2cc1468da177 1125
<> 161:2cc1468da177 1126 /* Check for error conditions */
<> 161:2cc1468da177 1127 errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_HS_SWITCH, SDMMC_CMDTIMEOUT);
<> 161:2cc1468da177 1128
<> 161:2cc1468da177 1129 return errorstate;
<> 161:2cc1468da177 1130 }
<> 161:2cc1468da177 1131
<> 144:ef7eb2e8f9f7 1132 /**
<> 144:ef7eb2e8f9f7 1133 * @}
<> 144:ef7eb2e8f9f7 1134 */
<> 144:ef7eb2e8f9f7 1135
<> 161:2cc1468da177 1136 /* Private function ----------------------------------------------------------*/
<> 161:2cc1468da177 1137 /** @addtogroup SD_Private_Functions
<> 161:2cc1468da177 1138 * @{
<> 161:2cc1468da177 1139 */
<> 161:2cc1468da177 1140
<> 161:2cc1468da177 1141 /**
<> 161:2cc1468da177 1142 * @brief Checks for error conditions for CMD0.
<> 161:2cc1468da177 1143 * @param hsd: SD handle
<> 161:2cc1468da177 1144 * @retval SD Card error state
<> 161:2cc1468da177 1145 */
<> 161:2cc1468da177 1146 static uint32_t SDMMC_GetCmdError(SDMMC_TypeDef *SDMMCx)
<> 161:2cc1468da177 1147 {
<> 161:2cc1468da177 1148 /* 8 is the number of required instructions cycles for the below loop statement.
<> 161:2cc1468da177 1149 The SDMMC_CMDTIMEOUT is expressed in ms */
<> 161:2cc1468da177 1150 register uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8 /1000);
<> 161:2cc1468da177 1151
<> 161:2cc1468da177 1152 do
<> 161:2cc1468da177 1153 {
<> 161:2cc1468da177 1154 if (count-- == 0)
<> 161:2cc1468da177 1155 {
<> 161:2cc1468da177 1156 return SDMMC_ERROR_TIMEOUT;
<> 161:2cc1468da177 1157 }
<> 161:2cc1468da177 1158
<> 161:2cc1468da177 1159 }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CMDSENT));
<> 161:2cc1468da177 1160
<> 161:2cc1468da177 1161 /* Clear all the static flags */
<> 161:2cc1468da177 1162 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_FLAGS);
<> 161:2cc1468da177 1163
<> 161:2cc1468da177 1164 return SDMMC_ERROR_NONE;
<> 161:2cc1468da177 1165 }
<> 161:2cc1468da177 1166
<> 161:2cc1468da177 1167 /**
<> 161:2cc1468da177 1168 * @brief Checks for error conditions for R1 response.
<> 161:2cc1468da177 1169 * @param hsd: SD handle
<> 161:2cc1468da177 1170 * @param SD_CMD: The sent command index
<> 161:2cc1468da177 1171 * @retval SD Card error state
<> 161:2cc1468da177 1172 */
<> 161:2cc1468da177 1173 static uint32_t SDMMC_GetCmdResp1(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint32_t Timeout)
<> 161:2cc1468da177 1174 {
<> 161:2cc1468da177 1175 uint32_t response_r1;
<> 161:2cc1468da177 1176
<> 161:2cc1468da177 1177 /* 8 is the number of required instructions cycles for the below loop statement.
<> 161:2cc1468da177 1178 The Timeout is expressed in ms */
<> 161:2cc1468da177 1179 register uint32_t count = Timeout * (SystemCoreClock / 8 /1000);
<> 161:2cc1468da177 1180
<> 161:2cc1468da177 1181 do
<> 161:2cc1468da177 1182 {
<> 161:2cc1468da177 1183 if (count-- == 0)
<> 161:2cc1468da177 1184 {
<> 161:2cc1468da177 1185 return SDMMC_ERROR_TIMEOUT;
<> 161:2cc1468da177 1186 }
<> 161:2cc1468da177 1187
<> 161:2cc1468da177 1188 }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT));
<> 161:2cc1468da177 1189
<> 161:2cc1468da177 1190 if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
<> 161:2cc1468da177 1191 {
<> 161:2cc1468da177 1192 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
<> 161:2cc1468da177 1193
<> 161:2cc1468da177 1194 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
<> 161:2cc1468da177 1195 }
<> 161:2cc1468da177 1196 else if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL))
<> 161:2cc1468da177 1197 {
<> 161:2cc1468da177 1198 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL);
<> 161:2cc1468da177 1199
<> 161:2cc1468da177 1200 return SDMMC_ERROR_CMD_CRC_FAIL;
<> 161:2cc1468da177 1201 }
<> 161:2cc1468da177 1202
<> 161:2cc1468da177 1203 /* Check response received is of desired command */
<> 161:2cc1468da177 1204 if(SDMMC_GetCommandResponse(SDMMCx) != SD_CMD)
<> 161:2cc1468da177 1205 {
<> 161:2cc1468da177 1206 return SDMMC_ERROR_CMD_CRC_FAIL;
<> 161:2cc1468da177 1207 }
<> 161:2cc1468da177 1208
<> 161:2cc1468da177 1209 /* Clear all the static flags */
<> 161:2cc1468da177 1210 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_FLAGS);
<> 161:2cc1468da177 1211
<> 161:2cc1468da177 1212 /* We have received response, retrieve it for analysis */
<> 161:2cc1468da177 1213 response_r1 = SDMMC_GetResponse(SDMMCx, SDMMC_RESP1);
<> 161:2cc1468da177 1214
<> 161:2cc1468da177 1215 if((response_r1 & SDMMC_OCR_ERRORBITS) == SDMMC_ALLZERO)
<> 161:2cc1468da177 1216 {
<> 161:2cc1468da177 1217 return SDMMC_ERROR_NONE;
<> 161:2cc1468da177 1218 }
<> 161:2cc1468da177 1219 else if((response_r1 & SDMMC_OCR_ADDR_OUT_OF_RANGE) == SDMMC_OCR_ADDR_OUT_OF_RANGE)
<> 161:2cc1468da177 1220 {
<> 161:2cc1468da177 1221 return SDMMC_ERROR_ADDR_OUT_OF_RANGE;
<> 161:2cc1468da177 1222 }
<> 161:2cc1468da177 1223 else if((response_r1 & SDMMC_OCR_ADDR_MISALIGNED) == SDMMC_OCR_ADDR_MISALIGNED)
<> 161:2cc1468da177 1224 {
<> 161:2cc1468da177 1225 return SDMMC_ERROR_ADDR_MISALIGNED;
<> 161:2cc1468da177 1226 }
<> 161:2cc1468da177 1227 else if((response_r1 & SDMMC_OCR_BLOCK_LEN_ERR) == SDMMC_OCR_BLOCK_LEN_ERR)
<> 161:2cc1468da177 1228 {
<> 161:2cc1468da177 1229 return SDMMC_ERROR_BLOCK_LEN_ERR;
<> 161:2cc1468da177 1230 }
<> 161:2cc1468da177 1231 else if((response_r1 & SDMMC_OCR_ERASE_SEQ_ERR) == SDMMC_OCR_ERASE_SEQ_ERR)
<> 161:2cc1468da177 1232 {
<> 161:2cc1468da177 1233 return SDMMC_ERROR_ERASE_SEQ_ERR;
<> 161:2cc1468da177 1234 }
<> 161:2cc1468da177 1235 else if((response_r1 & SDMMC_OCR_BAD_ERASE_PARAM) == SDMMC_OCR_BAD_ERASE_PARAM)
<> 161:2cc1468da177 1236 {
<> 161:2cc1468da177 1237 return SDMMC_ERROR_BAD_ERASE_PARAM;
<> 161:2cc1468da177 1238 }
<> 161:2cc1468da177 1239 else if((response_r1 & SDMMC_OCR_WRITE_PROT_VIOLATION) == SDMMC_OCR_WRITE_PROT_VIOLATION)
<> 161:2cc1468da177 1240 {
<> 161:2cc1468da177 1241 return SDMMC_ERROR_WRITE_PROT_VIOLATION;
<> 161:2cc1468da177 1242 }
<> 161:2cc1468da177 1243 else if((response_r1 & SDMMC_OCR_LOCK_UNLOCK_FAILED) == SDMMC_OCR_LOCK_UNLOCK_FAILED)
<> 161:2cc1468da177 1244 {
<> 161:2cc1468da177 1245 return SDMMC_ERROR_LOCK_UNLOCK_FAILED;
<> 161:2cc1468da177 1246 }
<> 161:2cc1468da177 1247 else if((response_r1 & SDMMC_OCR_COM_CRC_FAILED) == SDMMC_OCR_COM_CRC_FAILED)
<> 161:2cc1468da177 1248 {
<> 161:2cc1468da177 1249 return SDMMC_ERROR_COM_CRC_FAILED;
<> 161:2cc1468da177 1250 }
<> 161:2cc1468da177 1251 else if((response_r1 & SDMMC_OCR_ILLEGAL_CMD) == SDMMC_OCR_ILLEGAL_CMD)
<> 161:2cc1468da177 1252 {
<> 161:2cc1468da177 1253 return SDMMC_ERROR_ILLEGAL_CMD;
<> 161:2cc1468da177 1254 }
<> 161:2cc1468da177 1255 else if((response_r1 & SDMMC_OCR_CARD_ECC_FAILED) == SDMMC_OCR_CARD_ECC_FAILED)
<> 161:2cc1468da177 1256 {
<> 161:2cc1468da177 1257 return SDMMC_ERROR_CARD_ECC_FAILED;
<> 161:2cc1468da177 1258 }
<> 161:2cc1468da177 1259 else if((response_r1 & SDMMC_OCR_CC_ERROR) == SDMMC_OCR_CC_ERROR)
<> 161:2cc1468da177 1260 {
<> 161:2cc1468da177 1261 return SDMMC_ERROR_CC_ERR;
<> 161:2cc1468da177 1262 }
<> 161:2cc1468da177 1263 else if((response_r1 & SDMMC_OCR_STREAM_READ_UNDERRUN) == SDMMC_OCR_STREAM_READ_UNDERRUN)
<> 161:2cc1468da177 1264 {
<> 161:2cc1468da177 1265 return SDMMC_ERROR_STREAM_READ_UNDERRUN;
<> 161:2cc1468da177 1266 }
<> 161:2cc1468da177 1267 else if((response_r1 & SDMMC_OCR_STREAM_WRITE_OVERRUN) == SDMMC_OCR_STREAM_WRITE_OVERRUN)
<> 161:2cc1468da177 1268 {
<> 161:2cc1468da177 1269 return SDMMC_ERROR_STREAM_WRITE_OVERRUN;
<> 161:2cc1468da177 1270 }
<> 161:2cc1468da177 1271 else if((response_r1 & SDMMC_OCR_CID_CSD_OVERWRITE) == SDMMC_OCR_CID_CSD_OVERWRITE)
<> 161:2cc1468da177 1272 {
<> 161:2cc1468da177 1273 return SDMMC_ERROR_CID_CSD_OVERWRITE;
<> 161:2cc1468da177 1274 }
<> 161:2cc1468da177 1275 else if((response_r1 & SDMMC_OCR_WP_ERASE_SKIP) == SDMMC_OCR_WP_ERASE_SKIP)
<> 161:2cc1468da177 1276 {
<> 161:2cc1468da177 1277 return SDMMC_ERROR_WP_ERASE_SKIP;
<> 161:2cc1468da177 1278 }
<> 161:2cc1468da177 1279 else if((response_r1 & SDMMC_OCR_CARD_ECC_DISABLED) == SDMMC_OCR_CARD_ECC_DISABLED)
<> 161:2cc1468da177 1280 {
<> 161:2cc1468da177 1281 return SDMMC_ERROR_CARD_ECC_DISABLED;
<> 161:2cc1468da177 1282 }
<> 161:2cc1468da177 1283 else if((response_r1 & SDMMC_OCR_ERASE_RESET) == SDMMC_OCR_ERASE_RESET)
<> 161:2cc1468da177 1284 {
<> 161:2cc1468da177 1285 return SDMMC_ERROR_ERASE_RESET;
<> 161:2cc1468da177 1286 }
<> 161:2cc1468da177 1287 else if((response_r1 & SDMMC_OCR_AKE_SEQ_ERROR) == SDMMC_OCR_AKE_SEQ_ERROR)
<> 161:2cc1468da177 1288 {
<> 161:2cc1468da177 1289 return SDMMC_ERROR_AKE_SEQ_ERR;
<> 161:2cc1468da177 1290 }
<> 161:2cc1468da177 1291 else
<> 161:2cc1468da177 1292 {
<> 161:2cc1468da177 1293 return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
<> 161:2cc1468da177 1294 }
<> 161:2cc1468da177 1295 }
<> 161:2cc1468da177 1296
<> 161:2cc1468da177 1297 /**
<> 161:2cc1468da177 1298 * @brief Checks for error conditions for R2 (CID or CSD) response.
<> 161:2cc1468da177 1299 * @param hsd: SD handle
<> 161:2cc1468da177 1300 * @retval SD Card error state
<> 161:2cc1468da177 1301 */
<> 161:2cc1468da177 1302 static uint32_t SDMMC_GetCmdResp2(SDMMC_TypeDef *SDMMCx)
<> 161:2cc1468da177 1303 {
<> 161:2cc1468da177 1304 /* 8 is the number of required instructions cycles for the below loop statement.
<> 161:2cc1468da177 1305 The SDMMC_CMDTIMEOUT is expressed in ms */
<> 161:2cc1468da177 1306 register uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8 /1000);
<> 161:2cc1468da177 1307
<> 161:2cc1468da177 1308 do
<> 161:2cc1468da177 1309 {
<> 161:2cc1468da177 1310 if (count-- == 0)
<> 161:2cc1468da177 1311 {
<> 161:2cc1468da177 1312 return SDMMC_ERROR_TIMEOUT;
<> 161:2cc1468da177 1313 }
<> 161:2cc1468da177 1314
<> 161:2cc1468da177 1315 }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT));
<> 161:2cc1468da177 1316
<> 161:2cc1468da177 1317 if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
<> 161:2cc1468da177 1318 {
<> 161:2cc1468da177 1319 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
<> 161:2cc1468da177 1320
<> 161:2cc1468da177 1321 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
<> 161:2cc1468da177 1322 }
<> 161:2cc1468da177 1323 else if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL))
<> 161:2cc1468da177 1324 {
<> 161:2cc1468da177 1325 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL);
<> 161:2cc1468da177 1326
<> 161:2cc1468da177 1327 return SDMMC_ERROR_CMD_CRC_FAIL;
<> 161:2cc1468da177 1328 }
<> 161:2cc1468da177 1329 else
<> 161:2cc1468da177 1330 {
<> 161:2cc1468da177 1331 /* No error flag set */
<> 161:2cc1468da177 1332 /* Clear all the static flags */
<> 161:2cc1468da177 1333 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_FLAGS);
<> 161:2cc1468da177 1334 }
<> 161:2cc1468da177 1335
<> 161:2cc1468da177 1336 return SDMMC_ERROR_NONE;
<> 161:2cc1468da177 1337 }
<> 161:2cc1468da177 1338
<> 161:2cc1468da177 1339 /**
<> 161:2cc1468da177 1340 * @brief Checks for error conditions for R3 (OCR) response.
<> 161:2cc1468da177 1341 * @param hsd: SD handle
<> 161:2cc1468da177 1342 * @retval SD Card error state
<> 161:2cc1468da177 1343 */
<> 161:2cc1468da177 1344 static uint32_t SDMMC_GetCmdResp3(SDMMC_TypeDef *SDMMCx)
<> 161:2cc1468da177 1345 {
<> 161:2cc1468da177 1346 /* 8 is the number of required instructions cycles for the below loop statement.
<> 161:2cc1468da177 1347 The SDMMC_CMDTIMEOUT is expressed in ms */
<> 161:2cc1468da177 1348 register uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8 /1000);
<> 161:2cc1468da177 1349
<> 161:2cc1468da177 1350 do
<> 161:2cc1468da177 1351 {
<> 161:2cc1468da177 1352 if (count-- == 0)
<> 161:2cc1468da177 1353 {
<> 161:2cc1468da177 1354 return SDMMC_ERROR_TIMEOUT;
<> 161:2cc1468da177 1355 }
<> 161:2cc1468da177 1356
<> 161:2cc1468da177 1357 }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT));
<> 161:2cc1468da177 1358
<> 161:2cc1468da177 1359 if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
<> 161:2cc1468da177 1360 {
<> 161:2cc1468da177 1361 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
<> 161:2cc1468da177 1362
<> 161:2cc1468da177 1363 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
<> 161:2cc1468da177 1364 }
<> 161:2cc1468da177 1365 else
<> 161:2cc1468da177 1366
<> 161:2cc1468da177 1367 {
<> 161:2cc1468da177 1368 /* Clear all the static flags */
<> 161:2cc1468da177 1369 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_FLAGS);
<> 161:2cc1468da177 1370 }
<> 161:2cc1468da177 1371
<> 161:2cc1468da177 1372 return SDMMC_ERROR_NONE;
<> 161:2cc1468da177 1373 }
<> 161:2cc1468da177 1374
<> 161:2cc1468da177 1375 /**
<> 161:2cc1468da177 1376 * @brief Checks for error conditions for R6 (RCA) response.
<> 161:2cc1468da177 1377 * @param hsd: SD handle
<> 161:2cc1468da177 1378 * @param SD_CMD: The sent command index
<> 161:2cc1468da177 1379 * @param pRCA: Pointer to the variable that will contain the SD card relative
<> 161:2cc1468da177 1380 * address RCA
<> 161:2cc1468da177 1381 * @retval SD Card error state
<> 161:2cc1468da177 1382 */
<> 161:2cc1468da177 1383 static uint32_t SDMMC_GetCmdResp6(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint16_t *pRCA)
<> 161:2cc1468da177 1384 {
<> 161:2cc1468da177 1385 uint32_t response_r1;
<> 161:2cc1468da177 1386
<> 161:2cc1468da177 1387 /* 8 is the number of required instructions cycles for the below loop statement.
<> 161:2cc1468da177 1388 The SDMMC_CMDTIMEOUT is expressed in ms */
<> 161:2cc1468da177 1389 register uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8 /1000);
<> 161:2cc1468da177 1390
<> 161:2cc1468da177 1391 do
<> 161:2cc1468da177 1392 {
<> 161:2cc1468da177 1393 if (count-- == 0)
<> 161:2cc1468da177 1394 {
<> 161:2cc1468da177 1395 return SDMMC_ERROR_TIMEOUT;
<> 161:2cc1468da177 1396 }
<> 161:2cc1468da177 1397
<> 161:2cc1468da177 1398 }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT));
<> 161:2cc1468da177 1399
<> 161:2cc1468da177 1400 if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
<> 161:2cc1468da177 1401 {
<> 161:2cc1468da177 1402 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
<> 161:2cc1468da177 1403
<> 161:2cc1468da177 1404 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
<> 161:2cc1468da177 1405 }
<> 161:2cc1468da177 1406 else if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL))
<> 161:2cc1468da177 1407 {
<> 161:2cc1468da177 1408 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL);
<> 161:2cc1468da177 1409
<> 161:2cc1468da177 1410 return SDMMC_ERROR_CMD_CRC_FAIL;
<> 161:2cc1468da177 1411 }
<> 161:2cc1468da177 1412
<> 161:2cc1468da177 1413 /* Check response received is of desired command */
<> 161:2cc1468da177 1414 if(SDMMC_GetCommandResponse(SDMMCx) != SD_CMD)
<> 161:2cc1468da177 1415 {
<> 161:2cc1468da177 1416 return SDMMC_ERROR_CMD_CRC_FAIL;
<> 161:2cc1468da177 1417 }
<> 161:2cc1468da177 1418
<> 161:2cc1468da177 1419 /* Clear all the static flags */
<> 161:2cc1468da177 1420 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_FLAGS);
<> 161:2cc1468da177 1421
<> 161:2cc1468da177 1422 /* We have received response, retrieve it. */
<> 161:2cc1468da177 1423 response_r1 = SDMMC_GetResponse(SDMMCx, SDMMC_RESP1);
<> 161:2cc1468da177 1424
<> 161:2cc1468da177 1425 if((response_r1 & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | SDMMC_R6_COM_CRC_FAILED)) == SDMMC_ALLZERO)
<> 161:2cc1468da177 1426 {
<> 161:2cc1468da177 1427 *pRCA = (uint16_t) (response_r1 >> 16);
<> 161:2cc1468da177 1428
<> 161:2cc1468da177 1429 return SDMMC_ERROR_NONE;
<> 161:2cc1468da177 1430 }
<> 161:2cc1468da177 1431 else if((response_r1 & SDMMC_R6_ILLEGAL_CMD) == SDMMC_R6_ILLEGAL_CMD)
<> 161:2cc1468da177 1432 {
<> 161:2cc1468da177 1433 return SDMMC_ERROR_ILLEGAL_CMD;
<> 161:2cc1468da177 1434 }
<> 161:2cc1468da177 1435 else if((response_r1 & SDMMC_R6_COM_CRC_FAILED) == SDMMC_R6_COM_CRC_FAILED)
<> 161:2cc1468da177 1436 {
<> 161:2cc1468da177 1437 return SDMMC_ERROR_COM_CRC_FAILED;
<> 161:2cc1468da177 1438 }
<> 161:2cc1468da177 1439 else
<> 161:2cc1468da177 1440 {
<> 161:2cc1468da177 1441 return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
<> 161:2cc1468da177 1442 }
<> 161:2cc1468da177 1443 }
<> 161:2cc1468da177 1444
<> 161:2cc1468da177 1445 /**
<> 161:2cc1468da177 1446 * @brief Checks for error conditions for R7 response.
<> 161:2cc1468da177 1447 * @param hsd: SD handle
<> 161:2cc1468da177 1448 * @retval SD Card error state
<> 161:2cc1468da177 1449 */
<> 161:2cc1468da177 1450 static uint32_t SDMMC_GetCmdResp7(SDMMC_TypeDef *SDMMCx)
<> 161:2cc1468da177 1451 {
<> 161:2cc1468da177 1452 /* 8 is the number of required instructions cycles for the below loop statement.
<> 161:2cc1468da177 1453 The SDMMC_CMDTIMEOUT is expressed in ms */
<> 161:2cc1468da177 1454 register uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8 /1000);
<> 161:2cc1468da177 1455
<> 161:2cc1468da177 1456 do
<> 161:2cc1468da177 1457 {
<> 161:2cc1468da177 1458 if (count-- == 0)
<> 161:2cc1468da177 1459 {
<> 161:2cc1468da177 1460 return SDMMC_ERROR_TIMEOUT;
<> 161:2cc1468da177 1461 }
<> 161:2cc1468da177 1462
<> 161:2cc1468da177 1463 }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT));
<> 161:2cc1468da177 1464
<> 161:2cc1468da177 1465 if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
<> 161:2cc1468da177 1466 {
<> 161:2cc1468da177 1467 /* Card is SD V2.0 compliant */
<> 161:2cc1468da177 1468 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CMDREND);
<> 161:2cc1468da177 1469
<> 161:2cc1468da177 1470 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
<> 161:2cc1468da177 1471 }
<> 161:2cc1468da177 1472
<> 161:2cc1468da177 1473 if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CMDREND))
<> 161:2cc1468da177 1474 {
<> 161:2cc1468da177 1475 /* Card is SD V2.0 compliant */
<> 161:2cc1468da177 1476 __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CMDREND);
<> 161:2cc1468da177 1477 }
<> 161:2cc1468da177 1478
<> 161:2cc1468da177 1479 return SDMMC_ERROR_NONE;
<> 161:2cc1468da177 1480
<> 161:2cc1468da177 1481 }
<> 161:2cc1468da177 1482
<> 161:2cc1468da177 1483 /**
<> 161:2cc1468da177 1484 * @}
<> 161:2cc1468da177 1485 */
<> 161:2cc1468da177 1486
<> 161:2cc1468da177 1487 /**
<> 161:2cc1468da177 1488 * @}
<> 161:2cc1468da177 1489 */
<> 161:2cc1468da177 1490
<> 161:2cc1468da177 1491 #endif /* (HAL_SD_MODULE_ENABLED) */
<> 144:ef7eb2e8f9f7 1492 /**
<> 144:ef7eb2e8f9f7 1493 * @}
<> 144:ef7eb2e8f9f7 1494 */
<> 144:ef7eb2e8f9f7 1495
<> 144:ef7eb2e8f9f7 1496 /**
<> 144:ef7eb2e8f9f7 1497 * @}
<> 144:ef7eb2e8f9f7 1498 */
<> 144:ef7eb2e8f9f7 1499
<> 144:ef7eb2e8f9f7 1500 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/