Subversion Repositories LedShow

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f1xx_hal_sd.c
4
  * @author  MCD Application Team
5
  * @brief   SD card HAL module driver.
9 mjames 6
  *          This file provides firmware functions to manage the following
2 mjames 7
  *          functionalities of the Secure Digital (SD) peripheral:
8
  *           + Initialization and de-initialization functions
9
  *           + IO operation functions
9 mjames 10
  *           + Peripheral Control functions
11
  *           + Peripheral State functions
12
  *
2 mjames 13
  @verbatim
14
  ==============================================================================
15
                        ##### How to use this driver #####
16
  ==============================================================================
17
  [..]
9 mjames 18
    This driver implements a high level communication layer for read and write from/to
19
    this memory. The needed STM32 hardware resources (SDIO and GPIO) are performed by
20
    the user in HAL_SD_MspInit() function (MSP layer).
21
    Basically, the MSP layer configuration should be the same as we provide in the
2 mjames 22
    examples.
23
    You can easily tailor this configuration according to hardware resources.
24
 
25
  [..]
9 mjames 26
    This driver is a generic layered driver for SDIO memories which uses the HAL
27
    SDIO driver functions to interface with SD and uSD cards devices.
2 mjames 28
    It is used as follows:
9 mjames 29
 
30
    (#)Initialize the SDIO low level resources by implementing the HAL_SD_MspInit() API:
31
        (##) Enable the SDIO interface clock using __HAL_RCC_SDIO_CLK_ENABLE();
2 mjames 32
        (##) SDIO pins configuration for SD card
9 mjames 33
            (+++) Enable the clock for the SDIO GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
2 mjames 34
            (+++) Configure these SDIO pins as alternate function pull-up using HAL_GPIO_Init()
35
                  and according to your pin assignment;
9 mjames 36
        (##) DMA configuration if you need to use DMA process (HAL_SD_ReadBlocks_DMA()
2 mjames 37
             and HAL_SD_WriteBlocks_DMA() APIs).
9 mjames 38
            (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE();
39
            (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled.
2 mjames 40
        (##) NVIC configuration if you need to use interrupt process when using DMA transfer.
41
            (+++) Configure the SDIO and DMA interrupt priorities using functions
42
                  HAL_NVIC_SetPriority(); DMA priority is superior to SDIO's priority
43
            (+++) Enable the NVIC DMA and SDIO IRQs using function HAL_NVIC_EnableIRQ()
9 mjames 44
            (+++) SDIO interrupts are managed using the macros __HAL_SD_ENABLE_IT()
2 mjames 45
                  and __HAL_SD_DISABLE_IT() inside the communication process.
46
            (+++) SDIO interrupts pending bits are managed using the macros __HAL_SD_GET_IT()
47
                  and __HAL_SD_CLEAR_IT()
48
        (##) NVIC configuration if you need to use interrupt process (HAL_SD_ReadBlocks_IT()
49
             and HAL_SD_WriteBlocks_IT() APIs).
9 mjames 50
            (+++) Configure the SDIO interrupt priorities using function HAL_NVIC_SetPriority();
2 mjames 51
            (+++) Enable the NVIC SDIO IRQs using function HAL_NVIC_EnableIRQ()
9 mjames 52
            (+++) SDIO interrupts are managed using the macros __HAL_SD_ENABLE_IT()
2 mjames 53
                  and __HAL_SD_DISABLE_IT() inside the communication process.
54
            (+++) SDIO interrupts pending bits are managed using the macros __HAL_SD_GET_IT()
55
                  and __HAL_SD_CLEAR_IT()
9 mjames 56
    (#) At this stage, you can perform SD read/write/erase operations after SD card initialization
2 mjames 57
 
9 mjames 58
 
2 mjames 59
  *** SD Card Initialization and configuration ***
9 mjames 60
  ================================================
2 mjames 61
  [..]
9 mjames 62
    To initialize the SD Card, use the HAL_SD_Init() function. It Initializes
63
    SDIO Peripheral(STM32 side) and the SD Card, and put it into StandBy State (Ready for data transfer).
2 mjames 64
    This function provide the following operations:
65
 
9 mjames 66
    (#) Apply the SD Card initialization process at 400KHz and check the SD Card
67
        type (Standard Capacity or High Capacity). You can change or adapt this
68
        frequency by adjusting the "ClockDiv" field.
2 mjames 69
        The SD Card frequency (SDIO_CK) is computed as follows:
9 mjames 70
 
2 mjames 71
           SDIO_CK = SDIOCLK / (ClockDiv + 2)
9 mjames 72
 
73
        In initialization mode and according to the SD Card standard,
2 mjames 74
        make sure that the SDIO_CK frequency doesn't exceed 400KHz.
75
 
9 mjames 76
        This phase of initialization is done through SDIO_Init() and
2 mjames 77
        SDIO_PowerState_ON() SDIO low level APIs.
78
 
79
    (#) Initialize the SD card. The API used is HAL_SD_InitCard().
9 mjames 80
        This phase allows the card initialization and identification
2 mjames 81
        and check the SD Card type (Standard Capacity or High Capacity)
82
        The initialization flow is compatible with SD standard.
83
 
9 mjames 84
        This API (HAL_SD_InitCard()) could be used also to reinitialize the card in case
2 mjames 85
        of plug-off plug-in.
9 mjames 86
 
87
    (#) Configure the SD Card Data transfer frequency. You can change or adapt this
88
        frequency by adjusting the "ClockDiv" field.
89
        In transfer mode and according to the SD Card standard, make sure that the
2 mjames 90
        SDIO_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch.
9 mjames 91
        To be able to use a frequency higher than 24MHz, you should use the SDIO
92
        peripheral in bypass mode. Refer to the corresponding reference manual
2 mjames 93
        for more details.
9 mjames 94
 
2 mjames 95
    (#) Select the corresponding SD Card according to the address read with the step 2.
9 mjames 96
 
2 mjames 97
    (#) Configure the SD Card in wide bus mode: 4-bits data.
9 mjames 98
 
2 mjames 99
  *** SD Card Read operation ***
100
  ==============================
9 mjames 101
  [..]
102
    (+) You can read from SD card in polling mode by using function HAL_SD_ReadBlocks().
103
        This function support only 512-bytes block length (the block size should be
104
        chosen as 512 bytes).
105
        You can choose either one block read operation or multiple block read operation
2 mjames 106
        by adjusting the "NumberOfBlocks" parameter.
107
        After this, you have to ensure that the transfer is done correctly. The check is done
108
        through HAL_SD_GetCardState() function for SD card state.
109
 
110
    (+) You can read from SD card in DMA mode by using function HAL_SD_ReadBlocks_DMA().
9 mjames 111
        This function support only 512-bytes block length (the block size should be
112
        chosen as 512 bytes).
113
        You can choose either one block read operation or multiple block read operation
2 mjames 114
        by adjusting the "NumberOfBlocks" parameter.
115
        After this, you have to ensure that the transfer is done correctly. The check is done
116
        through HAL_SD_GetCardState() function for SD card state.
117
        You could also check the DMA transfer process through the SD Rx interrupt event.
118
 
119
    (+) You can read from SD card in Interrupt mode by using function HAL_SD_ReadBlocks_IT().
9 mjames 120
        This function support only 512-bytes block length (the block size should be
121
        chosen as 512 bytes).
122
        You can choose either one block read operation or multiple block read operation
2 mjames 123
        by adjusting the "NumberOfBlocks" parameter.
124
        After this, you have to ensure that the transfer is done correctly. The check is done
125
        through HAL_SD_GetCardState() function for SD card state.
126
        You could also check the IT transfer process through the SD Rx interrupt event.
9 mjames 127
 
2 mjames 128
  *** SD Card Write operation ***
9 mjames 129
  ===============================
130
  [..]
131
    (+) You can write to SD card in polling mode by using function HAL_SD_WriteBlocks().
132
        This function support only 512-bytes block length (the block size should be
133
        chosen as 512 bytes).
134
        You can choose either one block read operation or multiple block read operation
2 mjames 135
        by adjusting the "NumberOfBlocks" parameter.
136
        After this, you have to ensure that the transfer is done correctly. The check is done
137
        through HAL_SD_GetCardState() function for SD card state.
138
 
139
    (+) You can write to SD card in DMA mode by using function HAL_SD_WriteBlocks_DMA().
9 mjames 140
        This function support only 512-bytes block length (the block size should be
141
        chosen as 512 bytes).
142
        You can choose either one block read operation or multiple block read operation
2 mjames 143
        by adjusting the "NumberOfBlocks" parameter.
144
        After this, you have to ensure that the transfer is done correctly. The check is done
145
        through HAL_SD_GetCardState() function for SD card state.
9 mjames 146
        You could also check the DMA transfer process through the SD Tx interrupt event.
2 mjames 147
 
148
    (+) You can write to SD card in Interrupt mode by using function HAL_SD_WriteBlocks_IT().
9 mjames 149
        This function support only 512-bytes block length (the block size should be
150
        chosen as 512 bytes).
151
        You can choose either one block read operation or multiple block read operation
2 mjames 152
        by adjusting the "NumberOfBlocks" parameter.
153
        After this, you have to ensure that the transfer is done correctly. The check is done
154
        through HAL_SD_GetCardState() function for SD card state.
155
        You could also check the IT transfer process through the SD Tx interrupt event.
9 mjames 156
 
2 mjames 157
  *** SD card status ***
9 mjames 158
  ======================
2 mjames 159
  [..]
9 mjames 160
    (+) The SD Status contains status bits that are related to the SD Memory
2 mjames 161
        Card proprietary features. To get SD card status use the HAL_SD_GetCardStatus().
162
 
163
  *** SD card information ***
9 mjames 164
  ===========================
2 mjames 165
  [..]
166
    (+) To get SD card information, you can use the function HAL_SD_GetCardInfo().
167
        It returns useful information about the SD card such as block size, card type,
168
        block number ...
169
 
170
  *** SD card CSD register ***
171
  ============================
172
    (+) The HAL_SD_GetCardCSD() API allows to get the parameters of the CSD register.
173
        Some of the CSD parameters are useful for card initialization and identification.
174
 
175
  *** SD card CID register ***
176
  ============================
177
    (+) The HAL_SD_GetCardCID() API allows to get the parameters of the CID register.
178
        Some of the CSD parameters are useful for card initialization and identification.
179
 
180
  *** SD HAL driver macros list ***
181
  ==================================
182
  [..]
183
    Below the list of most used macros in SD HAL driver.
9 mjames 184
 
2 mjames 185
    (+) __HAL_SD_ENABLE : Enable the SD device
186
    (+) __HAL_SD_DISABLE : Disable the SD device
187
    (+) __HAL_SD_DMA_ENABLE: Enable the SDIO DMA transfer
188
    (+) __HAL_SD_DMA_DISABLE: Disable the SDIO DMA transfer
189
    (+) __HAL_SD_ENABLE_IT: Enable the SD device interrupt
190
    (+) __HAL_SD_DISABLE_IT: Disable the SD device interrupt
191
    (+) __HAL_SD_GET_FLAG:Check whether the specified SD flag is set or not
192
    (+) __HAL_SD_CLEAR_FLAG: Clear the SD's pending flags
193
 
9 mjames 194
    (@) You can refer to the SD HAL driver header file for more useful macros
195
 
196
  *** Callback registration ***
197
  =============================================
198
  [..]
199
    The compilation define USE_HAL_SD_REGISTER_CALLBACKS when set to 1
200
    allows the user to configure dynamically the driver callbacks.
201
 
202
    Use Functions @ref HAL_SD_RegisterCallback() to register a user callback,
203
    it allows to register following callbacks:
204
      (+) TxCpltCallback : callback when a transmission transfer is completed.
205
      (+) RxCpltCallback : callback when a reception transfer is completed.
206
      (+) ErrorCallback : callback when error occurs.
207
      (+) AbortCpltCallback : callback when abort is completed.
208
      (+) MspInitCallback    : SD MspInit.
209
      (+) MspDeInitCallback  : SD MspDeInit.
210
    This function takes as parameters the HAL peripheral handle, the Callback ID
211
    and a pointer to the user callback function.
212
 
213
    Use function @ref HAL_SD_UnRegisterCallback() to reset a callback to the default
214
    weak (surcharged) function. It allows to reset following callbacks:
215
      (+) TxCpltCallback : callback when a transmission transfer is completed.
216
      (+) RxCpltCallback : callback when a reception transfer is completed.
217
      (+) ErrorCallback : callback when error occurs.
218
      (+) AbortCpltCallback : callback when abort is completed.
219
      (+) MspInitCallback    : SD MspInit.
220
      (+) MspDeInitCallback  : SD MspDeInit.
221
    This function) takes as parameters the HAL peripheral handle and the Callback ID.
222
 
223
    By default, after the @ref HAL_SD_Init and if the state is HAL_SD_STATE_RESET
224
    all callbacks are reset to the corresponding legacy weak (surcharged) functions.
225
    Exception done for MspInit and MspDeInit callbacks that are respectively
226
    reset to the legacy weak (surcharged) functions in the @ref HAL_SD_Init
227
    and @ref  HAL_SD_DeInit only when these callbacks are null (not registered beforehand).
228
    If not, MspInit or MspDeInit are not null, the @ref HAL_SD_Init and @ref HAL_SD_DeInit
229
    keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
230
 
231
    Callbacks can be registered/unregistered in READY state only.
232
    Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
233
    in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
234
    during the Init/DeInit.
235
    In that case first register the MspInit/MspDeInit user callbacks
236
    using @ref HAL_SD_RegisterCallback before calling @ref HAL_SD_DeInit
237
    or @ref HAL_SD_Init function.
238
 
239
    When The compilation define USE_HAL_SD_REGISTER_CALLBACKS is set to 0 or
240
    not defined, the callback registering feature is not available
241
    and weak (surcharged) callbacks are used.
242
 
2 mjames 243
  @endverbatim
244
  ******************************************************************************
245
  * @attention
246
  *
9 mjames 247
  * <h2><center>&copy; Copyright (c) 2018 STMicroelectronics.
248
  * All rights reserved.</center></h2>
2 mjames 249
  *
9 mjames 250
  * This software component is licensed by ST under BSD 3-Clause license,
251
  * the "License"; You may not use this file except in compliance with the
252
  * License. You may obtain a copy of the License at:
253
  *                       opensource.org/licenses/BSD-3-Clause
2 mjames 254
  *
255
  ******************************************************************************
9 mjames 256
  */
2 mjames 257
 
258
/* Includes ------------------------------------------------------------------*/
259
#include "stm32f1xx_hal.h"
260
 
9 mjames 261
#if defined(SDIO)
2 mjames 262
 
263
/** @addtogroup STM32F1xx_HAL_Driver
264
  * @{
265
  */
266
 
9 mjames 267
/** @addtogroup SD
2 mjames 268
  * @{
269
  */
9 mjames 270
 
2 mjames 271
#ifdef HAL_SD_MODULE_ENABLED
272
 
273
/* Private typedef -----------------------------------------------------------*/
274
/* Private define ------------------------------------------------------------*/
275
/** @addtogroup SD_Private_Defines
276
  * @{
277
  */
9 mjames 278
 
2 mjames 279
/**
280
  * @}
281
  */
9 mjames 282
 
2 mjames 283
/* Private macro -------------------------------------------------------------*/
284
/* Private variables ---------------------------------------------------------*/
285
/* Private function prototypes -----------------------------------------------*/
286
/* Private functions ---------------------------------------------------------*/
287
/** @defgroup SD_Private_Functions SD Private Functions
288
  * @{
289
  */
290
static uint32_t SD_InitCard(SD_HandleTypeDef *hsd);
9 mjames 291
static uint32_t SD_PowerON(SD_HandleTypeDef *hsd);
2 mjames 292
static uint32_t SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus);
293
static uint32_t SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus);
294
static uint32_t SD_WideBus_Enable(SD_HandleTypeDef *hsd);
295
static uint32_t SD_WideBus_Disable(SD_HandleTypeDef *hsd);
296
static uint32_t SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR);
9 mjames 297
static void SD_PowerOFF(SD_HandleTypeDef *hsd);
298
static void SD_Write_IT(SD_HandleTypeDef *hsd);
299
static void SD_Read_IT(SD_HandleTypeDef *hsd);
2 mjames 300
static void SD_DMATransmitCplt(DMA_HandleTypeDef *hdma);
301
static void SD_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
302
static void SD_DMAError(DMA_HandleTypeDef *hdma);
303
static void SD_DMATxAbort(DMA_HandleTypeDef *hdma);
304
static void SD_DMARxAbort(DMA_HandleTypeDef *hdma);
305
/**
306
  * @}
307
  */
308
 
309
/* Exported functions --------------------------------------------------------*/
310
/** @addtogroup SD_Exported_Functions
311
  * @{
312
  */
313
 
314
/** @addtogroup SD_Exported_Functions_Group1
9 mjames 315
 *  @brief   Initialization and de-initialization functions
2 mjames 316
 *
9 mjames 317
@verbatim
2 mjames 318
  ==============================================================================
319
          ##### Initialization and de-initialization functions #####
320
  ==============================================================================
9 mjames 321
  [..]
2 mjames 322
    This section provides functions allowing to initialize/de-initialize the SD
323
    card device to be ready for use.
324
 
325
@endverbatim
326
  * @{
327
  */
328
 
329
/**
9 mjames 330
  * @brief  Initializes the SD according to the specified parameters in the
2 mjames 331
            SD_HandleTypeDef and create the associated handle.
9 mjames 332
  * @param  hsd: Pointer to the SD handle
2 mjames 333
  * @retval HAL status
334
  */
335
HAL_StatusTypeDef HAL_SD_Init(SD_HandleTypeDef *hsd)
336
{
337
  /* Check the SD handle allocation */
338
  if(hsd == NULL)
339
  {
340
    return HAL_ERROR;
341
  }
342
 
343
  /* Check the parameters */
344
  assert_param(IS_SDIO_ALL_INSTANCE(hsd->Instance));
345
  assert_param(IS_SDIO_CLOCK_EDGE(hsd->Init.ClockEdge));
346
  assert_param(IS_SDIO_CLOCK_BYPASS(hsd->Init.ClockBypass));
347
  assert_param(IS_SDIO_CLOCK_POWER_SAVE(hsd->Init.ClockPowerSave));
348
  assert_param(IS_SDIO_BUS_WIDE(hsd->Init.BusWide));
349
  assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(hsd->Init.HardwareFlowControl));
350
  assert_param(IS_SDIO_CLKDIV(hsd->Init.ClockDiv));
351
 
352
  if(hsd->State == HAL_SD_STATE_RESET)
353
  {
354
    /* Allocate lock resource and initialize it */
355
    hsd->Lock = HAL_UNLOCKED;
9 mjames 356
#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
357
    /* Reset Callback pointers in HAL_SD_STATE_RESET only */
358
    hsd->TxCpltCallback    = HAL_SD_TxCpltCallback;
359
    hsd->RxCpltCallback    = HAL_SD_RxCpltCallback;
360
    hsd->ErrorCallback     = HAL_SD_ErrorCallback;
361
    hsd->AbortCpltCallback = HAL_SD_AbortCallback;
362
 
363
    if(hsd->MspInitCallback == NULL)
364
    {
365
      hsd->MspInitCallback = HAL_SD_MspInit;
366
    }
367
 
368
    /* Init the low level hardware */
369
    hsd->MspInitCallback(hsd);
370
#else
2 mjames 371
    /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
372
    HAL_SD_MspInit(hsd);
9 mjames 373
#endif /* USE_HAL_SD_REGISTER_CALLBACKS */
2 mjames 374
  }
375
 
376
  hsd->State = HAL_SD_STATE_BUSY;
377
 
378
  /* Initialize the Card parameters */
9 mjames 379
  if (HAL_SD_InitCard(hsd) != HAL_OK)
380
  {
381
    return HAL_ERROR;
382
  }
2 mjames 383
 
384
  /* Initialize the error code */
9 mjames 385
  hsd->ErrorCode = HAL_SD_ERROR_NONE;
386
 
2 mjames 387
  /* Initialize the SD operation */
388
  hsd->Context = SD_CONTEXT_NONE;
9 mjames 389
 
2 mjames 390
  /* Initialize the SD state */
391
  hsd->State = HAL_SD_STATE_READY;
392
 
393
  return HAL_OK;
394
}
395
 
396
/**
397
  * @brief  Initializes the SD Card.
398
  * @param  hsd: Pointer to SD handle
9 mjames 399
  * @note   This function initializes the SD card. It could be used when a card
2 mjames 400
            re-initialization is needed.
401
  * @retval HAL status
402
  */
403
HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd)
404
{
9 mjames 405
  uint32_t errorstate;
406
  HAL_StatusTypeDef status;
2 mjames 407
  SD_InitTypeDef Init;
408
 
409
  /* Default SDIO peripheral configuration for SD card initialization */
410
  Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
411
  Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
412
  Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
413
  Init.BusWide             = SDIO_BUS_WIDE_1B;
414
  Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
415
  Init.ClockDiv            = SDIO_INIT_CLK_DIV;
416
 
417
  /* Initialize SDIO peripheral interface with default configuration */
9 mjames 418
  status = SDIO_Init(hsd->Instance, Init);
419
  if(status != HAL_OK)
420
  {
421
    return HAL_ERROR;
422
  }
2 mjames 423
 
424
  /* Disable SDIO Clock */
9 mjames 425
  __HAL_SD_DISABLE(hsd);
426
 
2 mjames 427
  /* Set Power State to ON */
9 mjames 428
  (void)SDIO_PowerState_ON(hsd->Instance);
429
 
2 mjames 430
  /* Enable SDIO Clock */
431
  __HAL_SD_ENABLE(hsd);
9 mjames 432
 
2 mjames 433
  /* Identify card operating voltage */
434
  errorstate = SD_PowerON(hsd);
435
  if(errorstate != HAL_SD_ERROR_NONE)
436
  {
437
    hsd->State = HAL_SD_STATE_READY;
438
    hsd->ErrorCode |= errorstate;
439
    return HAL_ERROR;
440
  }
441
 
442
  /* Card initialization */
443
  errorstate = SD_InitCard(hsd);
444
  if(errorstate != HAL_SD_ERROR_NONE)
445
  {
446
    hsd->State = HAL_SD_STATE_READY;
447
    hsd->ErrorCode |= errorstate;
448
    return HAL_ERROR;
449
  }
450
 
451
  return HAL_OK;
452
}
453
 
454
/**
455
  * @brief  De-Initializes the SD card.
456
  * @param  hsd: Pointer to SD handle
457
  * @retval HAL status
458
  */
459
HAL_StatusTypeDef HAL_SD_DeInit(SD_HandleTypeDef *hsd)
460
{
461
  /* Check the SD handle allocation */
462
  if(hsd == NULL)
463
  {
464
    return HAL_ERROR;
465
  }
9 mjames 466
 
2 mjames 467
  /* Check the parameters */
468
  assert_param(IS_SDIO_ALL_INSTANCE(hsd->Instance));
469
 
470
  hsd->State = HAL_SD_STATE_BUSY;
9 mjames 471
 
472
  /* Set SD power state to off */
2 mjames 473
  SD_PowerOFF(hsd);
9 mjames 474
 
475
#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
476
  if(hsd->MspDeInitCallback == NULL)
477
  {
478
    hsd->MspDeInitCallback = HAL_SD_MspDeInit;
479
  }
480
 
481
  /* DeInit the low level hardware */
482
  hsd->MspDeInitCallback(hsd);
483
#else
2 mjames 484
  /* De-Initialize the MSP layer */
485
  HAL_SD_MspDeInit(hsd);
9 mjames 486
#endif /* USE_HAL_SD_REGISTER_CALLBACKS */
487
 
2 mjames 488
  hsd->ErrorCode = HAL_SD_ERROR_NONE;
489
  hsd->State = HAL_SD_STATE_RESET;
9 mjames 490
 
2 mjames 491
  return HAL_OK;
492
}
493
 
494
 
495
/**
496
  * @brief  Initializes the SD MSP.
497
  * @param  hsd: Pointer to SD handle
498
  * @retval None
499
  */
500
__weak void HAL_SD_MspInit(SD_HandleTypeDef *hsd)
501
{
502
  /* Prevent unused argument(s) compilation warning */
503
  UNUSED(hsd);
9 mjames 504
 
505
  /* NOTE : This function should not be modified, when the callback is needed,
2 mjames 506
            the HAL_SD_MspInit could be implemented in the user file
507
   */
508
}
509
 
510
/**
511
  * @brief  De-Initialize SD MSP.
512
  * @param  hsd: Pointer to SD handle
513
  * @retval None
514
  */
515
__weak void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd)
516
{
517
  /* Prevent unused argument(s) compilation warning */
518
  UNUSED(hsd);
9 mjames 519
 
520
  /* NOTE : This function should not be modified, when the callback is needed,
2 mjames 521
            the HAL_SD_MspDeInit could be implemented in the user file
522
   */
523
}
524
 
525
/**
526
  * @}
527
  */
528
 
529
/** @addtogroup SD_Exported_Functions_Group2
9 mjames 530
 *  @brief   Data transfer functions
2 mjames 531
 *
9 mjames 532
@verbatim
2 mjames 533
  ==============================================================================
534
                        ##### IO operation functions #####
9 mjames 535
  ==============================================================================
2 mjames 536
  [..]
9 mjames 537
    This subsection provides a set of functions allowing to manage the data
2 mjames 538
    transfer from/to SD card.
539
 
540
@endverbatim
541
  * @{
542
  */
543
 
544
/**
9 mjames 545
  * @brief  Reads block(s) from a specified address in a card. The Data transfer
2 mjames 546
  *         is managed by polling mode.
547
  * @note   This API should be followed by a check on the card state through
548
  *         HAL_SD_GetCardState().
549
  * @param  hsd: Pointer to SD handle
550
  * @param  pData: pointer to the buffer that will contain the received data
9 mjames 551
  * @param  BlockAdd: Block Address from where data is to be read
2 mjames 552
  * @param  NumberOfBlocks: Number of SD blocks to read
553
  * @param  Timeout: Specify timeout value
554
  * @retval HAL status
555
  */
556
HAL_StatusTypeDef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
557
{
558
  SDIO_DataInitTypeDef config;
9 mjames 559
  uint32_t errorstate;
2 mjames 560
  uint32_t tickstart = HAL_GetTick();
9 mjames 561
  uint32_t count, data, dataremaining;
562
  uint32_t add = BlockAdd;
563
  uint8_t *tempbuff = pData;
564
 
2 mjames 565
  if(NULL == pData)
566
  {
567
    hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
568
    return HAL_ERROR;
569
  }
9 mjames 570
 
2 mjames 571
  if(hsd->State == HAL_SD_STATE_READY)
572
  {
9 mjames 573
    hsd->ErrorCode = HAL_SD_ERROR_NONE;
574
 
575
    if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
2 mjames 576
    {
577
      hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
578
      return HAL_ERROR;
579
    }
9 mjames 580
 
2 mjames 581
    hsd->State = HAL_SD_STATE_BUSY;
9 mjames 582
 
2 mjames 583
    /* Initialize data control register */
584
    hsd->Instance->DCTRL = 0U;
9 mjames 585
 
2 mjames 586
    if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
587
    {
9 mjames 588
      add *= 512U;
2 mjames 589
    }
9 mjames 590
 
2 mjames 591
    /* Set Block Size for Card */
592
    errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
593
    if(errorstate != HAL_SD_ERROR_NONE)
594
    {
595
      /* Clear all the static flags */
9 mjames 596
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 597
      hsd->ErrorCode |= errorstate;
598
      hsd->State = HAL_SD_STATE_READY;
599
      return HAL_ERROR;
600
    }
9 mjames 601
 
2 mjames 602
    /* Configure the SD DPSM (Data Path State Machine) */
603
    config.DataTimeOut   = SDMMC_DATATIMEOUT;
604
    config.DataLength    = NumberOfBlocks * BLOCKSIZE;
605
    config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
606
    config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
607
    config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
608
    config.DPSM          = SDIO_DPSM_ENABLE;
9 mjames 609
    (void)SDIO_ConfigData(hsd->Instance, &config);
610
 
2 mjames 611
    /* Read block(s) in polling mode */
612
    if(NumberOfBlocks > 1U)
613
    {
614
      hsd->Context = SD_CONTEXT_READ_MULTIPLE_BLOCK;
9 mjames 615
 
616
      /* Read Multi Block command */
617
      errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add);
2 mjames 618
    }
619
    else
620
    {
621
      hsd->Context = SD_CONTEXT_READ_SINGLE_BLOCK;
9 mjames 622
 
2 mjames 623
      /* Read Single Block command */
9 mjames 624
      errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, add);
2 mjames 625
    }
626
    if(errorstate != HAL_SD_ERROR_NONE)
627
    {
628
      /* Clear all the static flags */
629
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
630
      hsd->ErrorCode |= errorstate;
631
      hsd->State = HAL_SD_STATE_READY;
9 mjames 632
      hsd->Context = SD_CONTEXT_NONE;
2 mjames 633
      return HAL_ERROR;
634
    }
9 mjames 635
 
2 mjames 636
    /* Poll on SDIO flags */
9 mjames 637
    dataremaining = config.DataLength;
638
    while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
2 mjames 639
    {
9 mjames 640
      if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF) && (dataremaining > 0U))
2 mjames 641
      {
642
        /* Read data from SDIO Rx FIFO */
643
        for(count = 0U; count < 8U; count++)
644
        {
9 mjames 645
          data = SDIO_ReadFIFO(hsd->Instance);
646
          *tempbuff = (uint8_t)(data & 0xFFU);
647
          tempbuff++;
648
          dataremaining--;
649
          *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
650
          tempbuff++;
651
          dataremaining--;
652
          *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
653
          tempbuff++;
654
          dataremaining--;
655
          *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
656
          tempbuff++;
657
          dataremaining--;
2 mjames 658
        }
659
      }
9 mjames 660
 
661
      if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
2 mjames 662
      {
663
        /* Clear all the static flags */
664
        __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
665
        hsd->ErrorCode |= HAL_SD_ERROR_TIMEOUT;
666
        hsd->State= HAL_SD_STATE_READY;
9 mjames 667
        hsd->Context = SD_CONTEXT_NONE;
2 mjames 668
        return HAL_TIMEOUT;
669
      }
670
    }
671
 
672
    /* Send stop transmission command in case of multiblock read */
673
    if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
9 mjames 674
    {
2 mjames 675
      if(hsd->SdCard.CardType != CARD_SECURED)
676
      {
677
        /* Send stop transmission command */
678
        errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
679
        if(errorstate != HAL_SD_ERROR_NONE)
680
        {
681
          /* Clear all the static flags */
682
          __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
683
          hsd->ErrorCode |= errorstate;
684
          hsd->State = HAL_SD_STATE_READY;
9 mjames 685
          hsd->Context = SD_CONTEXT_NONE;
2 mjames 686
          return HAL_ERROR;
687
        }
688
      }
689
    }
9 mjames 690
 
2 mjames 691
    /* Get error state */
692
    if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
693
    {
694
      /* Clear all the static flags */
695
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
696
      hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;
697
      hsd->State = HAL_SD_STATE_READY;
9 mjames 698
      hsd->Context = SD_CONTEXT_NONE;
2 mjames 699
      return HAL_ERROR;
700
    }
701
    else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
702
    {
703
      /* Clear all the static flags */
704
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
705
      hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL;
706
      hsd->State = HAL_SD_STATE_READY;
9 mjames 707
      hsd->Context = SD_CONTEXT_NONE;
2 mjames 708
      return HAL_ERROR;
709
    }
710
    else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
711
    {
712
      /* Clear all the static flags */
713
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
714
      hsd->ErrorCode |= HAL_SD_ERROR_RX_OVERRUN;
715
      hsd->State = HAL_SD_STATE_READY;
9 mjames 716
      hsd->Context = SD_CONTEXT_NONE;
2 mjames 717
      return HAL_ERROR;
718
    }
9 mjames 719
    else
720
    {
721
      /* Nothing to do */
722
    }
723
 
2 mjames 724
    /* Empty FIFO if there is still any data */
9 mjames 725
    while ((__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)) && (dataremaining > 0U))
2 mjames 726
    {
9 mjames 727
      data = SDIO_ReadFIFO(hsd->Instance);
728
      *tempbuff = (uint8_t)(data & 0xFFU);
2 mjames 729
      tempbuff++;
9 mjames 730
      dataremaining--;
731
      *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
732
      tempbuff++;
733
      dataremaining--;
734
      *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
735
      tempbuff++;
736
      dataremaining--;
737
      *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
738
      tempbuff++;
739
      dataremaining--;
740
 
741
      if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
2 mjames 742
      {
743
        /* Clear all the static flags */
9 mjames 744
        __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 745
        hsd->ErrorCode |= HAL_SD_ERROR_TIMEOUT;
746
        hsd->State= HAL_SD_STATE_READY;
9 mjames 747
        hsd->Context = SD_CONTEXT_NONE;
2 mjames 748
        return HAL_ERROR;
749
      }
750
    }
9 mjames 751
 
2 mjames 752
    /* Clear all the static flags */
9 mjames 753
    __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
754
 
2 mjames 755
    hsd->State = HAL_SD_STATE_READY;
9 mjames 756
 
2 mjames 757
    return HAL_OK;
758
  }
759
  else
760
  {
761
    hsd->ErrorCode |= HAL_SD_ERROR_BUSY;
762
    return HAL_ERROR;
763
  }
764
}
765
 
766
/**
767
  * @brief  Allows to write block(s) to a specified address in a card. The Data
768
  *         transfer is managed by polling mode.
769
  * @note   This API should be followed by a check on the card state through
770
  *         HAL_SD_GetCardState().
771
  * @param  hsd: Pointer to SD handle
772
  * @param  pData: pointer to the buffer that will contain the data to transmit
9 mjames 773
  * @param  BlockAdd: Block Address where data will be written
2 mjames 774
  * @param  NumberOfBlocks: Number of SD blocks to write
775
  * @param  Timeout: Specify timeout value
776
  * @retval HAL status
777
  */
778
HAL_StatusTypeDef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
779
{
780
  SDIO_DataInitTypeDef config;
9 mjames 781
  uint32_t errorstate;
2 mjames 782
  uint32_t tickstart = HAL_GetTick();
9 mjames 783
  uint32_t count, data, dataremaining;
784
  uint32_t add = BlockAdd;
785
  uint8_t *tempbuff = pData;
786
 
2 mjames 787
  if(NULL == pData)
788
  {
789
    hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
790
    return HAL_ERROR;
791
  }
792
 
793
  if(hsd->State == HAL_SD_STATE_READY)
794
  {
9 mjames 795
    hsd->ErrorCode = HAL_SD_ERROR_NONE;
796
 
797
    if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
2 mjames 798
    {
799
      hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
800
      return HAL_ERROR;
801
    }
9 mjames 802
 
2 mjames 803
    hsd->State = HAL_SD_STATE_BUSY;
9 mjames 804
 
2 mjames 805
    /* Initialize data control register */
806
    hsd->Instance->DCTRL = 0U;
9 mjames 807
 
2 mjames 808
    if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
809
    {
9 mjames 810
      add *= 512U;
2 mjames 811
    }
9 mjames 812
 
813
    /* Set Block Size for Card */
2 mjames 814
    errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
815
    if(errorstate != HAL_SD_ERROR_NONE)
816
    {
817
      /* Clear all the static flags */
9 mjames 818
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 819
      hsd->ErrorCode |= errorstate;
820
      hsd->State = HAL_SD_STATE_READY;
821
      return HAL_ERROR;
822
    }
9 mjames 823
 
824
    /* Configure the SD DPSM (Data Path State Machine) */
825
    config.DataTimeOut   = SDMMC_DATATIMEOUT;
826
    config.DataLength    = NumberOfBlocks * BLOCKSIZE;
827
    config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
828
    config.TransferDir   = SDIO_TRANSFER_DIR_TO_CARD;
829
    config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
830
    config.DPSM          = SDIO_DPSM_ENABLE;
831
    (void)SDIO_ConfigData(hsd->Instance, &config);
832
 
2 mjames 833
    /* Write Blocks in Polling mode */
834
    if(NumberOfBlocks > 1U)
835
    {
836
      hsd->Context = SD_CONTEXT_WRITE_MULTIPLE_BLOCK;
9 mjames 837
 
838
      /* Write Multi Block command */
839
      errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add);
2 mjames 840
    }
841
    else
842
    {
843
      hsd->Context = SD_CONTEXT_WRITE_SINGLE_BLOCK;
9 mjames 844
 
2 mjames 845
      /* Write Single Block command */
9 mjames 846
      errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, add);
2 mjames 847
    }
848
    if(errorstate != HAL_SD_ERROR_NONE)
849
    {
850
      /* Clear all the static flags */
9 mjames 851
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 852
      hsd->ErrorCode |= errorstate;
853
      hsd->State = HAL_SD_STATE_READY;
9 mjames 854
      hsd->Context = SD_CONTEXT_NONE;
2 mjames 855
      return HAL_ERROR;
856
    }
9 mjames 857
 
2 mjames 858
    /* Write block(s) in polling mode */
9 mjames 859
    dataremaining = config.DataLength;
2 mjames 860
    while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
861
    {
9 mjames 862
      if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXFIFOHE) && (dataremaining > 0U))
2 mjames 863
      {
864
        /* Write data to SDIO Tx FIFO */
865
        for(count = 0U; count < 8U; count++)
866
        {
9 mjames 867
          data = (uint32_t)(*tempbuff);
868
          tempbuff++;
869
          dataremaining--;
870
          data |= ((uint32_t)(*tempbuff) << 8U);
871
          tempbuff++;
872
          dataremaining--;
873
          data |= ((uint32_t)(*tempbuff) << 16U);
874
          tempbuff++;
875
          dataremaining--;
876
          data |= ((uint32_t)(*tempbuff) << 24U);
877
          tempbuff++;
878
          dataremaining--;
879
          (void)SDIO_WriteFIFO(hsd->Instance, &data);
2 mjames 880
        }
881
      }
9 mjames 882
 
883
      if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
2 mjames 884
      {
885
        /* Clear all the static flags */
9 mjames 886
        __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 887
        hsd->ErrorCode |= errorstate;
888
        hsd->State = HAL_SD_STATE_READY;
9 mjames 889
        hsd->Context = SD_CONTEXT_NONE;
2 mjames 890
        return HAL_TIMEOUT;
891
      }
892
    }
9 mjames 893
 
2 mjames 894
    /* Send stop transmission command in case of multiblock write */
895
    if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
9 mjames 896
    {
2 mjames 897
      if(hsd->SdCard.CardType != CARD_SECURED)
898
      {
899
        /* Send stop transmission command */
900
        errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
901
        if(errorstate != HAL_SD_ERROR_NONE)
902
        {
903
          /* Clear all the static flags */
9 mjames 904
          __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 905
          hsd->ErrorCode |= errorstate;
906
          hsd->State = HAL_SD_STATE_READY;
9 mjames 907
          hsd->Context = SD_CONTEXT_NONE;
2 mjames 908
          return HAL_ERROR;
909
        }
910
      }
911
    }
9 mjames 912
 
2 mjames 913
    /* Get error state */
914
    if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
915
    {
916
      /* Clear all the static flags */
917
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
918
      hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;
919
      hsd->State = HAL_SD_STATE_READY;
9 mjames 920
      hsd->Context = SD_CONTEXT_NONE;
2 mjames 921
      return HAL_ERROR;
922
    }
923
    else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
924
    {
925
      /* Clear all the static flags */
926
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
9 mjames 927
      hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL;
2 mjames 928
      hsd->State = HAL_SD_STATE_READY;
9 mjames 929
      hsd->Context = SD_CONTEXT_NONE;
2 mjames 930
      return HAL_ERROR;
931
    }
932
    else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR))
933
    {
934
      /* Clear all the static flags */
935
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
936
      hsd->ErrorCode |= HAL_SD_ERROR_TX_UNDERRUN;
937
      hsd->State = HAL_SD_STATE_READY;
9 mjames 938
      hsd->Context = SD_CONTEXT_NONE;
2 mjames 939
      return HAL_ERROR;
940
    }
9 mjames 941
    else
942
    {
943
      /* Nothing to do */
944
    }
945
 
2 mjames 946
    /* Clear all the static flags */
9 mjames 947
    __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
948
 
2 mjames 949
    hsd->State = HAL_SD_STATE_READY;
9 mjames 950
 
2 mjames 951
    return HAL_OK;
952
  }
953
  else
954
  {
955
    hsd->ErrorCode |= HAL_SD_ERROR_BUSY;
956
    return HAL_ERROR;
957
  }
958
}
959
 
960
/**
9 mjames 961
  * @brief  Reads block(s) from a specified address in a card. The Data transfer
962
  *         is managed in interrupt mode.
2 mjames 963
  * @note   This API should be followed by a check on the card state through
964
  *         HAL_SD_GetCardState().
9 mjames 965
  * @note   You could also check the IT transfer process through the SD Rx
2 mjames 966
  *         interrupt event.
9 mjames 967
  * @param  hsd: Pointer to SD handle
2 mjames 968
  * @param  pData: Pointer to the buffer that will contain the received data
9 mjames 969
  * @param  BlockAdd: Block Address from where data is to be read
2 mjames 970
  * @param  NumberOfBlocks: Number of blocks to read.
971
  * @retval HAL status
972
  */
973
HAL_StatusTypeDef HAL_SD_ReadBlocks_IT(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
974
{
975
  SDIO_DataInitTypeDef config;
9 mjames 976
  uint32_t errorstate;
977
  uint32_t add = BlockAdd;
978
 
2 mjames 979
  if(NULL == pData)
980
  {
981
    hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
982
    return HAL_ERROR;
983
  }
9 mjames 984
 
2 mjames 985
  if(hsd->State == HAL_SD_STATE_READY)
986
  {
9 mjames 987
    hsd->ErrorCode = HAL_SD_ERROR_NONE;
988
 
989
    if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
2 mjames 990
    {
991
      hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
992
      return HAL_ERROR;
993
    }
9 mjames 994
 
2 mjames 995
    hsd->State = HAL_SD_STATE_BUSY;
9 mjames 996
 
2 mjames 997
    /* Initialize data control register */
998
    hsd->Instance->DCTRL = 0U;
9 mjames 999
 
1000
    hsd->pRxBuffPtr = pData;
2 mjames 1001
    hsd->RxXferSize = BLOCKSIZE * NumberOfBlocks;
9 mjames 1002
 
2 mjames 1003
    __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF | SDIO_IT_STBITERR));
1004
 
1005
    if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
1006
    {
9 mjames 1007
      add *= 512U;
2 mjames 1008
    }
9 mjames 1009
 
1010
    /* Set Block Size for Card */
2 mjames 1011
    errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
1012
    if(errorstate != HAL_SD_ERROR_NONE)
1013
    {
1014
      /* Clear all the static flags */
9 mjames 1015
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 1016
      hsd->ErrorCode |= errorstate;
1017
      hsd->State = HAL_SD_STATE_READY;
1018
      return HAL_ERROR;
1019
    }
1020
 
9 mjames 1021
    /* Configure the SD DPSM (Data Path State Machine) */
1022
    config.DataTimeOut   = SDMMC_DATATIMEOUT;
1023
    config.DataLength    = BLOCKSIZE * NumberOfBlocks;
1024
    config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1025
    config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
1026
    config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
1027
    config.DPSM          = SDIO_DPSM_ENABLE;
1028
    (void)SDIO_ConfigData(hsd->Instance, &config);
1029
 
2 mjames 1030
    /* Read Blocks in IT mode */
1031
    if(NumberOfBlocks > 1U)
1032
    {
1033
      hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_IT);
9 mjames 1034
 
2 mjames 1035
      /* Read Multi Block command */
9 mjames 1036
      errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add);
2 mjames 1037
    }
1038
    else
1039
    {
1040
      hsd->Context = (SD_CONTEXT_READ_SINGLE_BLOCK | SD_CONTEXT_IT);
9 mjames 1041
 
2 mjames 1042
      /* Read Single Block command */
9 mjames 1043
      errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, add);
2 mjames 1044
    }
1045
    if(errorstate != HAL_SD_ERROR_NONE)
1046
    {
1047
      /* Clear all the static flags */
9 mjames 1048
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 1049
      hsd->ErrorCode |= errorstate;
1050
      hsd->State = HAL_SD_STATE_READY;
9 mjames 1051
      hsd->Context = SD_CONTEXT_NONE;
2 mjames 1052
      return HAL_ERROR;
1053
    }
9 mjames 1054
 
2 mjames 1055
    return HAL_OK;
1056
  }
1057
  else
1058
  {
1059
    return HAL_BUSY;
1060
  }
1061
}
1062
 
1063
/**
9 mjames 1064
  * @brief  Writes block(s) to a specified address in a card. The Data transfer
1065
  *         is managed in interrupt mode.
2 mjames 1066
  * @note   This API should be followed by a check on the card state through
1067
  *         HAL_SD_GetCardState().
9 mjames 1068
  * @note   You could also check the IT transfer process through the SD Tx
1069
  *         interrupt event.
2 mjames 1070
  * @param  hsd: Pointer to SD handle
1071
  * @param  pData: Pointer to the buffer that will contain the data to transmit
9 mjames 1072
  * @param  BlockAdd: Block Address where data will be written
2 mjames 1073
  * @param  NumberOfBlocks: Number of blocks to write
1074
  * @retval HAL status
1075
  */
1076
HAL_StatusTypeDef HAL_SD_WriteBlocks_IT(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1077
{
1078
  SDIO_DataInitTypeDef config;
9 mjames 1079
  uint32_t errorstate;
1080
  uint32_t add = BlockAdd;
1081
 
2 mjames 1082
  if(NULL == pData)
1083
  {
1084
    hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
1085
    return HAL_ERROR;
1086
  }
9 mjames 1087
 
2 mjames 1088
  if(hsd->State == HAL_SD_STATE_READY)
1089
  {
9 mjames 1090
    hsd->ErrorCode = HAL_SD_ERROR_NONE;
1091
 
1092
    if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
2 mjames 1093
    {
1094
      hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
1095
      return HAL_ERROR;
1096
    }
9 mjames 1097
 
2 mjames 1098
    hsd->State = HAL_SD_STATE_BUSY;
9 mjames 1099
 
2 mjames 1100
    /* Initialize data control register */
1101
    hsd->Instance->DCTRL = 0U;
9 mjames 1102
 
1103
    hsd->pTxBuffPtr = pData;
2 mjames 1104
    hsd->TxXferSize = BLOCKSIZE * NumberOfBlocks;
9 mjames 1105
 
2 mjames 1106
    /* Enable transfer interrupts */
9 mjames 1107
    __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE | SDIO_IT_STBITERR));
1108
 
2 mjames 1109
    if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
1110
    {
9 mjames 1111
      add *= 512U;
2 mjames 1112
    }
9 mjames 1113
 
1114
    /* Set Block Size for Card */
2 mjames 1115
    errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
1116
    if(errorstate != HAL_SD_ERROR_NONE)
1117
    {
1118
      /* Clear all the static flags */
9 mjames 1119
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 1120
      hsd->ErrorCode |= errorstate;
1121
      hsd->State = HAL_SD_STATE_READY;
1122
      return HAL_ERROR;
1123
    }
9 mjames 1124
 
2 mjames 1125
    /* Write Blocks in Polling mode */
1126
    if(NumberOfBlocks > 1U)
1127
    {
1128
      hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK| SD_CONTEXT_IT);
9 mjames 1129
 
1130
      /* Write Multi Block command */
1131
      errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add);
2 mjames 1132
    }
1133
    else
1134
    {
1135
      hsd->Context = (SD_CONTEXT_WRITE_SINGLE_BLOCK | SD_CONTEXT_IT);
9 mjames 1136
 
1137
      /* Write Single Block command */
1138
      errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, add);
2 mjames 1139
    }
1140
    if(errorstate != HAL_SD_ERROR_NONE)
1141
    {
1142
      /* Clear all the static flags */
9 mjames 1143
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 1144
      hsd->ErrorCode |= errorstate;
1145
      hsd->State = HAL_SD_STATE_READY;
9 mjames 1146
      hsd->Context = SD_CONTEXT_NONE;
2 mjames 1147
      return HAL_ERROR;
1148
    }
9 mjames 1149
 
1150
    /* Configure the SD DPSM (Data Path State Machine) */
2 mjames 1151
    config.DataTimeOut   = SDMMC_DATATIMEOUT;
1152
    config.DataLength    = BLOCKSIZE * NumberOfBlocks;
1153
    config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1154
    config.TransferDir   = SDIO_TRANSFER_DIR_TO_CARD;
1155
    config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
1156
    config.DPSM          = SDIO_DPSM_ENABLE;
9 mjames 1157
    (void)SDIO_ConfigData(hsd->Instance, &config);
1158
 
2 mjames 1159
    return HAL_OK;
1160
  }
1161
  else
1162
  {
1163
    return HAL_BUSY;
1164
  }
1165
}
1166
 
1167
/**
9 mjames 1168
  * @brief  Reads block(s) from a specified address in a card. The Data transfer
1169
  *         is managed by DMA mode.
2 mjames 1170
  * @note   This API should be followed by a check on the card state through
1171
  *         HAL_SD_GetCardState().
9 mjames 1172
  * @note   You could also check the DMA transfer process through the SD Rx
2 mjames 1173
  *         interrupt event.
9 mjames 1174
  * @param  hsd: Pointer SD handle
2 mjames 1175
  * @param  pData: Pointer to the buffer that will contain the received data
9 mjames 1176
  * @param  BlockAdd: Block Address from where data is to be read
2 mjames 1177
  * @param  NumberOfBlocks: Number of blocks to read.
1178
  * @retval HAL status
1179
  */
1180
HAL_StatusTypeDef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1181
{
1182
  SDIO_DataInitTypeDef config;
9 mjames 1183
  uint32_t errorstate;
1184
  uint32_t add = BlockAdd;
1185
 
2 mjames 1186
  if(NULL == pData)
1187
  {
1188
    hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
1189
    return HAL_ERROR;
1190
  }
9 mjames 1191
 
2 mjames 1192
  if(hsd->State == HAL_SD_STATE_READY)
1193
  {
9 mjames 1194
    hsd->ErrorCode = HAL_SD_ERROR_NONE;
1195
 
1196
    if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
2 mjames 1197
    {
1198
      hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
1199
      return HAL_ERROR;
1200
    }
9 mjames 1201
 
2 mjames 1202
    hsd->State = HAL_SD_STATE_BUSY;
9 mjames 1203
 
2 mjames 1204
    /* Initialize data control register */
1205
    hsd->Instance->DCTRL = 0U;
9 mjames 1206
 
2 mjames 1207
    __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_IT_STBITERR));
9 mjames 1208
 
2 mjames 1209
    /* Set the DMA transfer complete callback */
1210
    hsd->hdmarx->XferCpltCallback = SD_DMAReceiveCplt;
9 mjames 1211
 
2 mjames 1212
    /* Set the DMA error callback */
1213
    hsd->hdmarx->XferErrorCallback = SD_DMAError;
9 mjames 1214
 
2 mjames 1215
    /* Set the DMA Abort callback */
1216
    hsd->hdmarx->XferAbortCallback = NULL;
9 mjames 1217
 
2 mjames 1218
    /* Enable the DMA Channel */
9 mjames 1219
    if(HAL_DMA_Start_IT(hsd->hdmarx, (uint32_t)&hsd->Instance->FIFO, (uint32_t)pData, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4U) != HAL_OK)
2 mjames 1220
    {
9 mjames 1221
      __HAL_SD_DISABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
1222
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
1223
      hsd->ErrorCode |= HAL_SD_ERROR_DMA;
2 mjames 1224
      hsd->State = HAL_SD_STATE_READY;
1225
      return HAL_ERROR;
1226
    }
1227
    else
1228
    {
9 mjames 1229
      /* Enable SD DMA transfer */
1230
      __HAL_SD_DMA_ENABLE(hsd);
1231
 
1232
      if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
1233
      {
1234
        add *= 512U;
1235
      }
1236
 
1237
      /* Set Block Size for Card */
1238
      errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
1239
      if(errorstate != HAL_SD_ERROR_NONE)
1240
      {
1241
        /* Clear all the static flags */
1242
        __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
1243
        hsd->ErrorCode |= errorstate;
1244
        hsd->State = HAL_SD_STATE_READY;
1245
        return HAL_ERROR;
1246
      }
1247
 
1248
      /* Configure the SD DPSM (Data Path State Machine) */
1249
      config.DataTimeOut   = SDMMC_DATATIMEOUT;
1250
      config.DataLength    = BLOCKSIZE * NumberOfBlocks;
1251
      config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1252
      config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
1253
      config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
1254
      config.DPSM          = SDIO_DPSM_ENABLE;
1255
      (void)SDIO_ConfigData(hsd->Instance, &config);
1256
 
1257
      /* Read Blocks in DMA mode */
1258
      if(NumberOfBlocks > 1U)
1259
      {
1260
        hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA);
1261
 
1262
        /* Read Multi Block command */
1263
        errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add);
1264
      }
1265
      else
1266
      {
1267
        hsd->Context = (SD_CONTEXT_READ_SINGLE_BLOCK | SD_CONTEXT_DMA);
1268
 
1269
        /* Read Single Block command */
1270
        errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, add);
1271
      }
1272
      if(errorstate != HAL_SD_ERROR_NONE)
1273
      {
1274
        /* Clear all the static flags */
1275
        __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
1276
        hsd->ErrorCode |= errorstate;
1277
        hsd->State = HAL_SD_STATE_READY;
1278
        hsd->Context = SD_CONTEXT_NONE;
1279
        return HAL_ERROR;
1280
      }
1281
 
1282
      return HAL_OK;
2 mjames 1283
    }
1284
  }
1285
  else
1286
  {
1287
    return HAL_BUSY;
1288
  }
1289
}
1290
 
1291
/**
9 mjames 1292
  * @brief  Writes block(s) to a specified address in a card. The Data transfer
1293
  *         is managed by DMA mode.
2 mjames 1294
  * @note   This API should be followed by a check on the card state through
1295
  *         HAL_SD_GetCardState().
9 mjames 1296
  * @note   You could also check the DMA transfer process through the SD Tx
2 mjames 1297
  *         interrupt event.
1298
  * @param  hsd: Pointer to SD handle
1299
  * @param  pData: Pointer to the buffer that will contain the data to transmit
9 mjames 1300
  * @param  BlockAdd: Block Address where data will be written
2 mjames 1301
  * @param  NumberOfBlocks: Number of blocks to write
1302
  * @retval HAL status
1303
  */
1304
HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1305
{
1306
  SDIO_DataInitTypeDef config;
9 mjames 1307
  uint32_t errorstate;
1308
  uint32_t add = BlockAdd;
1309
 
2 mjames 1310
  if(NULL == pData)
1311
  {
1312
    hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
1313
    return HAL_ERROR;
1314
  }
9 mjames 1315
 
2 mjames 1316
  if(hsd->State == HAL_SD_STATE_READY)
1317
  {
9 mjames 1318
    hsd->ErrorCode = HAL_SD_ERROR_NONE;
1319
 
1320
    if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
2 mjames 1321
    {
1322
      hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
1323
      return HAL_ERROR;
1324
    }
9 mjames 1325
 
2 mjames 1326
    hsd->State = HAL_SD_STATE_BUSY;
9 mjames 1327
 
2 mjames 1328
    /* Initialize data control register */
1329
    hsd->Instance->DCTRL = 0U;
9 mjames 1330
 
1331
    /* Enable SD Error interrupts */
1332
    __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR));
1333
 
2 mjames 1334
    /* Set the DMA transfer complete callback */
1335
    hsd->hdmatx->XferCpltCallback = SD_DMATransmitCplt;
9 mjames 1336
 
2 mjames 1337
    /* Set the DMA error callback */
1338
    hsd->hdmatx->XferErrorCallback = SD_DMAError;
9 mjames 1339
 
2 mjames 1340
    /* Set the DMA Abort callback */
1341
    hsd->hdmatx->XferAbortCallback = NULL;
9 mjames 1342
 
2 mjames 1343
    if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
1344
    {
9 mjames 1345
      add *= 512U;
2 mjames 1346
    }
9 mjames 1347
 
1348
    /* Set Block Size for Card */
2 mjames 1349
    errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
1350
    if(errorstate != HAL_SD_ERROR_NONE)
1351
    {
1352
      /* Clear all the static flags */
9 mjames 1353
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 1354
      hsd->ErrorCode |= errorstate;
1355
      hsd->State = HAL_SD_STATE_READY;
1356
      return HAL_ERROR;
1357
    }
9 mjames 1358
 
2 mjames 1359
    /* Write Blocks in Polling mode */
1360
    if(NumberOfBlocks > 1U)
1361
    {
1362
      hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK | SD_CONTEXT_DMA);
9 mjames 1363
 
1364
      /* Write Multi Block command */
1365
      errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add);
2 mjames 1366
    }
1367
    else
1368
    {
1369
      hsd->Context = (SD_CONTEXT_WRITE_SINGLE_BLOCK | SD_CONTEXT_DMA);
9 mjames 1370
 
2 mjames 1371
      /* Write Single Block command */
9 mjames 1372
      errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, add);
2 mjames 1373
    }
1374
    if(errorstate != HAL_SD_ERROR_NONE)
1375
    {
1376
      /* Clear all the static flags */
9 mjames 1377
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 1378
      hsd->ErrorCode |= errorstate;
1379
      hsd->State = HAL_SD_STATE_READY;
9 mjames 1380
      hsd->Context = SD_CONTEXT_NONE;
2 mjames 1381
      return HAL_ERROR;
1382
    }
9 mjames 1383
 
2 mjames 1384
    /* Enable SDIO DMA transfer */
1385
    __HAL_SD_DMA_ENABLE(hsd);
9 mjames 1386
 
2 mjames 1387
    /* Enable the DMA Channel */
9 mjames 1388
    if(HAL_DMA_Start_IT(hsd->hdmatx, (uint32_t)pData, (uint32_t)&hsd->Instance->FIFO, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4U) != HAL_OK)
1389
    {
1390
      __HAL_SD_DISABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR));
1391
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
1392
      hsd->ErrorCode |= HAL_SD_ERROR_DMA;
1393
      hsd->State = HAL_SD_STATE_READY;
1394
      hsd->Context = SD_CONTEXT_NONE;
1395
      return HAL_ERROR;
1396
    }
1397
    else
1398
    {
1399
      /* Configure the SD DPSM (Data Path State Machine) */
1400
      config.DataTimeOut   = SDMMC_DATATIMEOUT;
1401
      config.DataLength    = BLOCKSIZE * NumberOfBlocks;
1402
      config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1403
      config.TransferDir   = SDIO_TRANSFER_DIR_TO_CARD;
1404
      config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
1405
      config.DPSM          = SDIO_DPSM_ENABLE;
1406
      (void)SDIO_ConfigData(hsd->Instance, &config);
1407
 
1408
      return HAL_OK;
1409
    }
2 mjames 1410
  }
1411
  else
1412
  {
1413
    return HAL_BUSY;
1414
  }
1415
}
1416
 
1417
/**
1418
  * @brief  Erases the specified memory area of the given SD card.
1419
  * @note   This API should be followed by a check on the card state through
1420
  *         HAL_SD_GetCardState().
9 mjames 1421
  * @param  hsd: Pointer to SD handle
2 mjames 1422
  * @param  BlockStartAdd: Start Block address
1423
  * @param  BlockEndAdd: End Block address
1424
  * @retval HAL status
1425
  */
1426
HAL_StatusTypeDef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
1427
{
9 mjames 1428
  uint32_t errorstate;
1429
  uint32_t start_add = BlockStartAdd;
1430
  uint32_t end_add = BlockEndAdd;
1431
 
2 mjames 1432
  if(hsd->State == HAL_SD_STATE_READY)
1433
  {
9 mjames 1434
    hsd->ErrorCode = HAL_SD_ERROR_NONE;
1435
 
1436
    if(end_add < start_add)
2 mjames 1437
    {
1438
      hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
1439
      return HAL_ERROR;
1440
    }
9 mjames 1441
 
1442
    if(end_add > (hsd->SdCard.LogBlockNbr))
2 mjames 1443
    {
1444
      hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
1445
      return HAL_ERROR;
1446
    }
9 mjames 1447
 
2 mjames 1448
    hsd->State = HAL_SD_STATE_BUSY;
9 mjames 1449
 
2 mjames 1450
    /* Check if the card command class supports erase command */
1451
    if(((hsd->SdCard.Class) & SDIO_CCCC_ERASE) == 0U)
1452
    {
1453
      /* Clear all the static flags */
1454
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
1455
      hsd->ErrorCode |= HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
1456
      hsd->State = HAL_SD_STATE_READY;
1457
      return HAL_ERROR;
1458
    }
9 mjames 1459
 
2 mjames 1460
    if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
1461
    {
1462
      /* Clear all the static flags */
9 mjames 1463
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 1464
      hsd->ErrorCode |= HAL_SD_ERROR_LOCK_UNLOCK_FAILED;
1465
      hsd->State = HAL_SD_STATE_READY;
1466
      return HAL_ERROR;
1467
    }
9 mjames 1468
 
2 mjames 1469
    /* Get start and end block for high capacity cards */
1470
    if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
1471
    {
9 mjames 1472
      start_add *= 512U;
1473
      end_add   *= 512U;
2 mjames 1474
    }
9 mjames 1475
 
2 mjames 1476
    /* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */
1477
    if(hsd->SdCard.CardType != CARD_SECURED)
1478
    {
1479
      /* Send CMD32 SD_ERASE_GRP_START with argument as addr  */
9 mjames 1480
      errorstate = SDMMC_CmdSDEraseStartAdd(hsd->Instance, start_add);
2 mjames 1481
      if(errorstate != HAL_SD_ERROR_NONE)
1482
      {
1483
        /* Clear all the static flags */
9 mjames 1484
        __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 1485
        hsd->ErrorCode |= errorstate;
1486
        hsd->State = HAL_SD_STATE_READY;
1487
        return HAL_ERROR;
1488
      }
9 mjames 1489
 
2 mjames 1490
      /* Send CMD33 SD_ERASE_GRP_END with argument as addr  */
9 mjames 1491
      errorstate = SDMMC_CmdSDEraseEndAdd(hsd->Instance, end_add);
2 mjames 1492
      if(errorstate != HAL_SD_ERROR_NONE)
1493
      {
1494
        /* Clear all the static flags */
9 mjames 1495
        __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 1496
        hsd->ErrorCode |= errorstate;
1497
        hsd->State = HAL_SD_STATE_READY;
1498
        return HAL_ERROR;
1499
      }
1500
    }
9 mjames 1501
 
2 mjames 1502
    /* Send CMD38 ERASE */
1503
    errorstate = SDMMC_CmdErase(hsd->Instance);
1504
    if(errorstate != HAL_SD_ERROR_NONE)
1505
    {
1506
      /* Clear all the static flags */
9 mjames 1507
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 1508
      hsd->ErrorCode |= errorstate;
1509
      hsd->State = HAL_SD_STATE_READY;
1510
      return HAL_ERROR;
1511
    }
9 mjames 1512
 
2 mjames 1513
    hsd->State = HAL_SD_STATE_READY;
9 mjames 1514
 
2 mjames 1515
    return HAL_OK;
1516
  }
1517
  else
1518
  {
1519
    return HAL_BUSY;
1520
  }
1521
}
1522
 
1523
/**
1524
  * @brief  This function handles SD card interrupt request.
1525
  * @param  hsd: Pointer to SD handle
1526
  * @retval None
1527
  */
1528
void HAL_SD_IRQHandler(SD_HandleTypeDef *hsd)
1529
{
9 mjames 1530
  uint32_t errorstate;
1531
  uint32_t context = hsd->Context;
1532
 
2 mjames 1533
  /* Check for SDIO interrupt flags */
9 mjames 1534
  if((__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF) != RESET) && ((context & SD_CONTEXT_IT) != 0U))
2 mjames 1535
  {
9 mjames 1536
    SD_Read_IT(hsd);
1537
  }
1538
 
1539
  else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DATAEND) != RESET)
1540
  {
1541
    __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_DATAEND);
1542
 
1543
    __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND  | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
1544
                             SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR  | SDIO_IT_TXFIFOHE |\
1545
                             SDIO_IT_RXFIFOHF | SDIO_IT_STBITERR);
1546
 
1547
    hsd->Instance->DCTRL &= ~(SDIO_DCTRL_DTEN);
2 mjames 1548
 
9 mjames 1549
    if((context & SD_CONTEXT_IT) != 0U)
2 mjames 1550
    {
9 mjames 1551
      if(((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
2 mjames 1552
      {
1553
        errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
1554
        if(errorstate != HAL_SD_ERROR_NONE)
1555
        {
1556
          hsd->ErrorCode |= errorstate;
9 mjames 1557
#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
1558
          hsd->ErrorCallback(hsd);
1559
#else
2 mjames 1560
          HAL_SD_ErrorCallback(hsd);
9 mjames 1561
#endif /* USE_HAL_SD_REGISTER_CALLBACKS */
2 mjames 1562
        }
1563
      }
9 mjames 1564
 
2 mjames 1565
      /* Clear all the static flags */
9 mjames 1566
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
1567
 
2 mjames 1568
      hsd->State = HAL_SD_STATE_READY;
9 mjames 1569
      hsd->Context = SD_CONTEXT_NONE;
1570
      if(((context & SD_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
2 mjames 1571
      {
9 mjames 1572
#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
1573
        hsd->RxCpltCallback(hsd);
1574
#else
2 mjames 1575
        HAL_SD_RxCpltCallback(hsd);
9 mjames 1576
#endif /* USE_HAL_SD_REGISTER_CALLBACKS */
2 mjames 1577
      }
1578
      else
1579
      {
9 mjames 1580
#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
1581
        hsd->TxCpltCallback(hsd);
1582
#else
2 mjames 1583
        HAL_SD_TxCpltCallback(hsd);
9 mjames 1584
#endif /* USE_HAL_SD_REGISTER_CALLBACKS */
2 mjames 1585
      }
1586
    }
9 mjames 1587
    else if((context & SD_CONTEXT_DMA) != 0U)
2 mjames 1588
    {
9 mjames 1589
      if((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
2 mjames 1590
      {
1591
        errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
1592
        if(errorstate != HAL_SD_ERROR_NONE)
1593
        {
1594
          hsd->ErrorCode |= errorstate;
9 mjames 1595
#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
1596
          hsd->ErrorCallback(hsd);
1597
#else
2 mjames 1598
          HAL_SD_ErrorCallback(hsd);
9 mjames 1599
#endif /* USE_HAL_SD_REGISTER_CALLBACKS */
2 mjames 1600
        }
1601
      }
9 mjames 1602
      if(((context & SD_CONTEXT_READ_SINGLE_BLOCK) == 0U) && ((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) == 0U))
2 mjames 1603
      {
1604
        /* Disable the DMA transfer for transmit request by setting the DMAEN bit
1605
        in the SD DCTRL register */
1606
        hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
9 mjames 1607
 
2 mjames 1608
        hsd->State = HAL_SD_STATE_READY;
9 mjames 1609
 
1610
#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
1611
        hsd->TxCpltCallback(hsd);
1612
#else
2 mjames 1613
        HAL_SD_TxCpltCallback(hsd);
9 mjames 1614
#endif /* USE_HAL_SD_REGISTER_CALLBACKS */
2 mjames 1615
      }
1616
    }
9 mjames 1617
    else
1618
    {
1619
      /* Nothing to do */
1620
    }
2 mjames 1621
  }
9 mjames 1622
 
1623
  else if((__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXFIFOHE) != RESET) && ((context & SD_CONTEXT_IT) != 0U))
2 mjames 1624
  {
1625
    SD_Write_IT(hsd);
1626
  }
9 mjames 1627
 
1628
  else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_RXOVERR | SDIO_FLAG_TXUNDERR | SDIO_FLAG_STBITERR) != RESET)
2 mjames 1629
  {
1630
    /* Set Error code */
9 mjames 1631
    if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL) != RESET)
2 mjames 1632
    {
9 mjames 1633
      hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL;
2 mjames 1634
    }
9 mjames 1635
    if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT) != RESET)
2 mjames 1636
    {
9 mjames 1637
      hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;
2 mjames 1638
    }
9 mjames 1639
    if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR) != RESET)
2 mjames 1640
    {
9 mjames 1641
      hsd->ErrorCode |= HAL_SD_ERROR_RX_OVERRUN;
2 mjames 1642
    }
9 mjames 1643
    if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR) != RESET)
2 mjames 1644
    {
9 mjames 1645
      hsd->ErrorCode |= HAL_SD_ERROR_TX_UNDERRUN;
2 mjames 1646
    }
9 mjames 1647
    if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_STBITERR) != RESET)
2 mjames 1648
    {
1649
      hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;
1650
    }
1651
 
1652
    /* Clear All flags */
9 mjames 1653
    __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS | SDIO_FLAG_STBITERR);
1654
 
2 mjames 1655
    /* Disable all interrupts */
1656
    __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
9 mjames 1657
                             SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR | SDIO_IT_STBITERR);
1658
 
1659
    hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance);
1660
 
1661
    if((context & SD_CONTEXT_IT) != 0U)
2 mjames 1662
    {
9 mjames 1663
      /* Set the SD state to ready to be able to start again the process */
1664
      hsd->State = HAL_SD_STATE_READY;
1665
      hsd->Context = SD_CONTEXT_NONE;
1666
#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
1667
      hsd->ErrorCallback(hsd);
1668
#else
1669
      HAL_SD_ErrorCallback(hsd);
1670
#endif /* USE_HAL_SD_REGISTER_CALLBACKS */
1671
    }
1672
    else if((context & SD_CONTEXT_DMA) != 0U)
1673
    {
1674
      /* Abort the SD DMA channel */
1675
      if(((context & SD_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
2 mjames 1676
      {
1677
        /* Set the DMA Tx abort callback */
1678
        hsd->hdmatx->XferAbortCallback = SD_DMATxAbort;
1679
        /* Abort DMA in IT mode */
1680
        if(HAL_DMA_Abort_IT(hsd->hdmatx) != HAL_OK)
1681
        {
1682
          SD_DMATxAbort(hsd->hdmatx);
1683
        }
1684
      }
9 mjames 1685
      else if(((context & SD_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
2 mjames 1686
      {
1687
        /* Set the DMA Rx abort callback */
1688
        hsd->hdmarx->XferAbortCallback = SD_DMARxAbort;
1689
        /* Abort DMA in IT mode */
1690
        if(HAL_DMA_Abort_IT(hsd->hdmarx) != HAL_OK)
1691
        {
1692
          SD_DMARxAbort(hsd->hdmarx);
1693
        }
1694
      }
1695
      else
1696
      {
1697
        hsd->ErrorCode = HAL_SD_ERROR_NONE;
1698
        hsd->State = HAL_SD_STATE_READY;
9 mjames 1699
        hsd->Context = SD_CONTEXT_NONE;
1700
#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
1701
        hsd->AbortCpltCallback(hsd);
1702
#else
2 mjames 1703
        HAL_SD_AbortCallback(hsd);
9 mjames 1704
#endif /* USE_HAL_SD_REGISTER_CALLBACKS */
2 mjames 1705
      }
1706
    }
9 mjames 1707
    else
2 mjames 1708
    {
9 mjames 1709
      /* Nothing to do */
2 mjames 1710
    }
1711
  }
9 mjames 1712
  else
1713
  {
1714
    /* Nothing to do */
1715
  }
2 mjames 1716
}
1717
 
1718
/**
1719
  * @brief return the SD state
1720
  * @param hsd: Pointer to sd handle
1721
  * @retval HAL state
1722
  */
1723
HAL_SD_StateTypeDef HAL_SD_GetState(SD_HandleTypeDef *hsd)
1724
{
1725
  return hsd->State;
1726
}
1727
 
1728
/**
1729
* @brief  Return the SD error code
1730
* @param  hsd : Pointer to a SD_HandleTypeDef structure that contains
1731
  *              the configuration information.
1732
* @retval SD Error Code
1733
*/
1734
uint32_t HAL_SD_GetError(SD_HandleTypeDef *hsd)
1735
{
1736
  return hsd->ErrorCode;
1737
}
1738
 
1739
/**
1740
  * @brief Tx Transfer completed callbacks
1741
  * @param hsd: Pointer to SD handle
1742
  * @retval None
1743
  */
9 mjames 1744
__weak void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
2 mjames 1745
{
1746
  /* Prevent unused argument(s) compilation warning */
1747
  UNUSED(hsd);
1748
 
1749
  /* NOTE : This function should not be modified, when the callback is needed,
1750
            the HAL_SD_TxCpltCallback can be implemented in the user file
1751
   */
1752
}
1753
 
1754
/**
1755
  * @brief Rx Transfer completed callbacks
1756
  * @param hsd: Pointer SD handle
1757
  * @retval None
1758
  */
1759
__weak void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
1760
{
1761
  /* Prevent unused argument(s) compilation warning */
1762
  UNUSED(hsd);
9 mjames 1763
 
2 mjames 1764
  /* NOTE : This function should not be modified, when the callback is needed,
1765
            the HAL_SD_RxCpltCallback can be implemented in the user file
1766
   */
1767
}
1768
 
1769
/**
1770
  * @brief SD error callbacks
1771
  * @param hsd: Pointer SD handle
1772
  * @retval None
1773
  */
1774
__weak void HAL_SD_ErrorCallback(SD_HandleTypeDef *hsd)
1775
{
1776
  /* Prevent unused argument(s) compilation warning */
1777
  UNUSED(hsd);
9 mjames 1778
 
2 mjames 1779
  /* NOTE : This function should not be modified, when the callback is needed,
1780
            the HAL_SD_ErrorCallback can be implemented in the user file
9 mjames 1781
   */
2 mjames 1782
}
1783
 
1784
/**
1785
  * @brief SD Abort callbacks
1786
  * @param hsd: Pointer SD handle
1787
  * @retval None
1788
  */
1789
__weak void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd)
1790
{
1791
  /* Prevent unused argument(s) compilation warning */
1792
  UNUSED(hsd);
9 mjames 1793
 
2 mjames 1794
  /* NOTE : This function should not be modified, when the callback is needed,
9 mjames 1795
            the HAL_SD_AbortCallback can be implemented in the user file
1796
   */
2 mjames 1797
}
1798
 
9 mjames 1799
#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
1800
/**
1801
  * @brief  Register a User SD Callback
1802
  *         To be used instead of the weak (surcharged) predefined callback
1803
  * @param hsd : SD handle
1804
  * @param CallbackID : ID of the callback to be registered
1805
  *        This parameter can be one of the following values:
1806
  *          @arg @ref HAL_SD_TX_CPLT_CB_ID    SD Tx Complete Callback ID
1807
  *          @arg @ref HAL_SD_RX_CPLT_CB_ID    SD Rx Complete Callback ID
1808
  *          @arg @ref HAL_SD_ERROR_CB_ID      SD Error Callback ID
1809
  *          @arg @ref HAL_SD_ABORT_CB_ID      SD Abort Callback ID
1810
  *          @arg @ref HAL_SD_MSP_INIT_CB_ID   SD MspInit Callback ID
1811
  *          @arg @ref HAL_SD_MSP_DEINIT_CB_ID SD MspDeInit Callback ID
1812
  * @param pCallback : pointer to the Callback function
1813
  * @retval status
1814
  */
1815
HAL_StatusTypeDef HAL_SD_RegisterCallback(SD_HandleTypeDef *hsd, HAL_SD_CallbackIDTypeDef CallbackID, pSD_CallbackTypeDef pCallback)
1816
{
1817
  HAL_StatusTypeDef status = HAL_OK;
2 mjames 1818
 
9 mjames 1819
  if(pCallback == NULL)
1820
  {
1821
    /* Update the error code */
1822
    hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK;
1823
    return HAL_ERROR;
1824
  }
1825
 
1826
  /* Process locked */
1827
  __HAL_LOCK(hsd);
1828
 
1829
  if(hsd->State == HAL_SD_STATE_READY)
1830
  {
1831
    switch (CallbackID)
1832
    {
1833
    case HAL_SD_TX_CPLT_CB_ID :
1834
      hsd->TxCpltCallback = pCallback;
1835
      break;
1836
    case HAL_SD_RX_CPLT_CB_ID :
1837
      hsd->RxCpltCallback = pCallback;
1838
      break;
1839
    case HAL_SD_ERROR_CB_ID :
1840
      hsd->ErrorCallback = pCallback;
1841
      break;
1842
    case HAL_SD_ABORT_CB_ID :
1843
      hsd->AbortCpltCallback = pCallback;
1844
      break;
1845
    case HAL_SD_MSP_INIT_CB_ID :
1846
      hsd->MspInitCallback = pCallback;
1847
      break;
1848
    case HAL_SD_MSP_DEINIT_CB_ID :
1849
      hsd->MspDeInitCallback = pCallback;
1850
      break;
1851
    default :
1852
      /* Update the error code */
1853
      hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK;
1854
      /* update return status */
1855
      status =  HAL_ERROR;
1856
      break;
1857
    }
1858
  }
1859
  else if (hsd->State == HAL_SD_STATE_RESET)
1860
  {
1861
    switch (CallbackID)
1862
    {
1863
    case HAL_SD_MSP_INIT_CB_ID :
1864
      hsd->MspInitCallback = pCallback;
1865
      break;
1866
    case HAL_SD_MSP_DEINIT_CB_ID :
1867
      hsd->MspDeInitCallback = pCallback;
1868
      break;
1869
    default :
1870
      /* Update the error code */
1871
      hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK;
1872
      /* update return status */
1873
      status =  HAL_ERROR;
1874
      break;
1875
    }
1876
  }
1877
  else
1878
  {
1879
    /* Update the error code */
1880
    hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK;
1881
    /* update return status */
1882
    status =  HAL_ERROR;
1883
  }
1884
 
1885
  /* Release Lock */
1886
  __HAL_UNLOCK(hsd);
1887
  return status;
1888
}
1889
 
2 mjames 1890
/**
9 mjames 1891
  * @brief  Unregister a User SD Callback
1892
  *         SD Callback is redirected to the weak (surcharged) predefined callback
1893
  * @param hsd : SD handle
1894
  * @param CallbackID : ID of the callback to be unregistered
1895
  *        This parameter can be one of the following values:
1896
  *          @arg @ref HAL_SD_TX_CPLT_CB_ID    SD Tx Complete Callback ID
1897
  *          @arg @ref HAL_SD_RX_CPLT_CB_ID    SD Rx Complete Callback ID
1898
  *          @arg @ref HAL_SD_ERROR_CB_ID      SD Error Callback ID
1899
  *          @arg @ref HAL_SD_ABORT_CB_ID      SD Abort Callback ID
1900
  *          @arg @ref HAL_SD_MSP_INIT_CB_ID   SD MspInit Callback ID
1901
  *          @arg @ref HAL_SD_MSP_DEINIT_CB_ID SD MspDeInit Callback ID
1902
  * @retval status
1903
  */
1904
HAL_StatusTypeDef HAL_SD_UnRegisterCallback(SD_HandleTypeDef *hsd, HAL_SD_CallbackIDTypeDef CallbackID)
1905
{
1906
  HAL_StatusTypeDef status = HAL_OK;
1907
 
1908
  /* Process locked */
1909
  __HAL_LOCK(hsd);
1910
 
1911
  if(hsd->State == HAL_SD_STATE_READY)
1912
  {
1913
    switch (CallbackID)
1914
    {
1915
    case HAL_SD_TX_CPLT_CB_ID :
1916
      hsd->TxCpltCallback = HAL_SD_TxCpltCallback;
1917
      break;
1918
    case HAL_SD_RX_CPLT_CB_ID :
1919
      hsd->RxCpltCallback = HAL_SD_RxCpltCallback;
1920
      break;
1921
    case HAL_SD_ERROR_CB_ID :
1922
      hsd->ErrorCallback = HAL_SD_ErrorCallback;
1923
      break;
1924
    case HAL_SD_ABORT_CB_ID :
1925
      hsd->AbortCpltCallback = HAL_SD_AbortCallback;
1926
      break;
1927
    case HAL_SD_MSP_INIT_CB_ID :
1928
      hsd->MspInitCallback = HAL_SD_MspInit;
1929
      break;
1930
    case HAL_SD_MSP_DEINIT_CB_ID :
1931
      hsd->MspDeInitCallback = HAL_SD_MspDeInit;
1932
      break;
1933
    default :
1934
      /* Update the error code */
1935
      hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK;
1936
      /* update return status */
1937
      status =  HAL_ERROR;
1938
      break;
1939
    }
1940
  }
1941
  else if (hsd->State == HAL_SD_STATE_RESET)
1942
  {
1943
    switch (CallbackID)
1944
    {
1945
    case HAL_SD_MSP_INIT_CB_ID :
1946
      hsd->MspInitCallback = HAL_SD_MspInit;
1947
      break;
1948
    case HAL_SD_MSP_DEINIT_CB_ID :
1949
      hsd->MspDeInitCallback = HAL_SD_MspDeInit;
1950
      break;
1951
    default :
1952
      /* Update the error code */
1953
      hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK;
1954
      /* update return status */
1955
      status =  HAL_ERROR;
1956
      break;
1957
    }
1958
  }
1959
  else
1960
  {
1961
    /* Update the error code */
1962
    hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK;
1963
    /* update return status */
1964
    status =  HAL_ERROR;
1965
  }
1966
 
1967
  /* Release Lock */
1968
  __HAL_UNLOCK(hsd);
1969
  return status;
1970
}
1971
#endif /* USE_HAL_SD_REGISTER_CALLBACKS */
1972
 
1973
/**
2 mjames 1974
  * @}
1975
  */
1976
 
1977
/** @addtogroup SD_Exported_Functions_Group3
9 mjames 1978
 *  @brief   management functions
2 mjames 1979
 *
9 mjames 1980
@verbatim
2 mjames 1981
  ==============================================================================
1982
                      ##### Peripheral Control functions #####
9 mjames 1983
  ==============================================================================
2 mjames 1984
  [..]
9 mjames 1985
    This subsection provides a set of functions allowing to control the SD card
2 mjames 1986
    operations and get the related information
1987
 
1988
@endverbatim
1989
  * @{
1990
  */
1991
 
1992
/**
1993
  * @brief  Returns information the information of the card which are stored on
1994
  *         the CID register.
1995
  * @param  hsd: Pointer to SD handle
9 mjames 1996
  * @param  pCID: Pointer to a HAL_SD_CardCIDTypeDef structure that  
1997
  *         contains all CID register parameters
2 mjames 1998
  * @retval HAL status
1999
  */
2000
HAL_StatusTypeDef HAL_SD_GetCardCID(SD_HandleTypeDef *hsd, HAL_SD_CardCIDTypeDef *pCID)
2001
{
9 mjames 2002
  pCID->ManufacturerID = (uint8_t)((hsd->CID[0] & 0xFF000000U) >> 24U);
2003
 
2004
  pCID->OEM_AppliID = (uint16_t)((hsd->CID[0] & 0x00FFFF00U) >> 8U);
2005
 
2006
  pCID->ProdName1 = (((hsd->CID[0] & 0x000000FFU) << 24U) | ((hsd->CID[1] & 0xFFFFFF00U) >> 8U));
2007
 
2008
  pCID->ProdName2 = (uint8_t)(hsd->CID[1] & 0x000000FFU);
2009
 
2010
  pCID->ProdRev = (uint8_t)((hsd->CID[2] & 0xFF000000U) >> 24U);
2011
 
2012
  pCID->ProdSN = (((hsd->CID[2] & 0x00FFFFFFU) << 8U) | ((hsd->CID[3] & 0xFF000000U) >> 24U));
2013
 
2014
  pCID->Reserved1 = (uint8_t)((hsd->CID[3] & 0x00F00000U) >> 20U);
2015
 
2016
  pCID->ManufactDate = (uint16_t)((hsd->CID[3] & 0x000FFF00U) >> 8U);
2017
 
2018
  pCID->CID_CRC = (uint8_t)((hsd->CID[3] & 0x000000FEU) >> 1U);
2019
 
2 mjames 2020
  pCID->Reserved2 = 1U;
2021
 
2022
  return HAL_OK;
2023
}
2024
 
2025
/**
2026
  * @brief  Returns information the information of the card which are stored on
2027
  *         the CSD register.
2028
  * @param  hsd: Pointer to SD handle
2029
  * @param  pCSD: Pointer to a HAL_SD_CardCSDTypeDef structure that  
9 mjames 2030
  *         contains all CSD register parameters
2 mjames 2031
  * @retval HAL status
2032
  */
2033
HAL_StatusTypeDef HAL_SD_GetCardCSD(SD_HandleTypeDef *hsd, HAL_SD_CardCSDTypeDef *pCSD)
2034
{
9 mjames 2035
  pCSD->CSDStruct = (uint8_t)((hsd->CSD[0] & 0xC0000000U) >> 30U);
2036
 
2037
  pCSD->SysSpecVersion = (uint8_t)((hsd->CSD[0] & 0x3C000000U) >> 26U);
2038
 
2039
  pCSD->Reserved1 = (uint8_t)((hsd->CSD[0] & 0x03000000U) >> 24U);
2040
 
2041
  pCSD->TAAC = (uint8_t)((hsd->CSD[0] & 0x00FF0000U) >> 16U);
2042
 
2043
  pCSD->NSAC = (uint8_t)((hsd->CSD[0] & 0x0000FF00U) >> 8U);
2044
 
2045
  pCSD->MaxBusClkFrec = (uint8_t)(hsd->CSD[0] & 0x000000FFU);
2046
 
2047
  pCSD->CardComdClasses = (uint16_t)((hsd->CSD[1] & 0xFFF00000U) >> 20U);
2048
 
2049
  pCSD->RdBlockLen = (uint8_t)((hsd->CSD[1] & 0x000F0000U) >> 16U);
2050
 
2051
  pCSD->PartBlockRead   = (uint8_t)((hsd->CSD[1] & 0x00008000U) >> 15U);
2052
 
2053
  pCSD->WrBlockMisalign = (uint8_t)((hsd->CSD[1] & 0x00004000U) >> 14U);
2054
 
2055
  pCSD->RdBlockMisalign = (uint8_t)((hsd->CSD[1] & 0x00002000U) >> 13U);
2056
 
2057
  pCSD->DSRImpl = (uint8_t)((hsd->CSD[1] & 0x00001000U) >> 12U);
2058
 
2059
  pCSD->Reserved2 = 0U; /*!< Reserved */
2060
 
2 mjames 2061
  if(hsd->SdCard.CardType == CARD_SDSC)
2062
  {
9 mjames 2063
    pCSD->DeviceSize = (((hsd->CSD[1] & 0x000003FFU) << 2U) | ((hsd->CSD[2] & 0xC0000000U) >> 30U));
2064
 
2065
    pCSD->MaxRdCurrentVDDMin = (uint8_t)((hsd->CSD[2] & 0x38000000U) >> 27U);
2066
 
2067
    pCSD->MaxRdCurrentVDDMax = (uint8_t)((hsd->CSD[2] & 0x07000000U) >> 24U);
2068
 
2069
    pCSD->MaxWrCurrentVDDMin = (uint8_t)((hsd->CSD[2] & 0x00E00000U) >> 21U);
2070
 
2071
    pCSD->MaxWrCurrentVDDMax = (uint8_t)((hsd->CSD[2] & 0x001C0000U) >> 18U);
2072
 
2073
    pCSD->DeviceSizeMul = (uint8_t)((hsd->CSD[2] & 0x00038000U) >> 15U);
2074
 
2 mjames 2075
    hsd->SdCard.BlockNbr  = (pCSD->DeviceSize + 1U) ;
9 mjames 2076
    hsd->SdCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U));
2077
    hsd->SdCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU));
2 mjames 2078
 
9 mjames 2079
    hsd->SdCard.LogBlockNbr =  (hsd->SdCard.BlockNbr) * ((hsd->SdCard.BlockSize) / 512U);
2 mjames 2080
    hsd->SdCard.LogBlockSize = 512U;
2081
  }
2082
  else if(hsd->SdCard.CardType == CARD_SDHC_SDXC)
2083
  {
2084
    /* Byte 7 */
9 mjames 2085
    pCSD->DeviceSize = (((hsd->CSD[1] & 0x0000003FU) << 16U) | ((hsd->CSD[2] & 0xFFFF0000U) >> 16U));
2086
 
2087
    hsd->SdCard.BlockNbr = ((pCSD->DeviceSize + 1U) * 1024U);
2088
    hsd->SdCard.LogBlockNbr = hsd->SdCard.BlockNbr;
2089
    hsd->SdCard.BlockSize = 512U;
2090
    hsd->SdCard.LogBlockSize = hsd->SdCard.BlockSize;
2 mjames 2091
  }
2092
  else
2093
  {
2094
    /* Clear all the static flags */
9 mjames 2095
    __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 2096
    hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
2097
    hsd->State = HAL_SD_STATE_READY;
2098
    return HAL_ERROR;
2099
  }
9 mjames 2100
 
2101
  pCSD->EraseGrSize = (uint8_t)((hsd->CSD[2] & 0x00004000U) >> 14U);
2102
 
2103
  pCSD->EraseGrMul = (uint8_t)((hsd->CSD[2] & 0x00003F80U) >> 7U);
2104
 
2105
  pCSD->WrProtectGrSize = (uint8_t)(hsd->CSD[2] & 0x0000007FU);
2106
 
2107
  pCSD->WrProtectGrEnable = (uint8_t)((hsd->CSD[3] & 0x80000000U) >> 31U);
2108
 
2109
  pCSD->ManDeflECC = (uint8_t)((hsd->CSD[3] & 0x60000000U) >> 29U);
2110
 
2111
  pCSD->WrSpeedFact = (uint8_t)((hsd->CSD[3] & 0x1C000000U) >> 26U);
2112
 
2113
  pCSD->MaxWrBlockLen= (uint8_t)((hsd->CSD[3] & 0x03C00000U) >> 22U);
2114
 
2115
  pCSD->WriteBlockPaPartial = (uint8_t)((hsd->CSD[3] & 0x00200000U) >> 21U);
2116
 
2117
  pCSD->Reserved3 = 0;
2118
 
2119
  pCSD->ContentProtectAppli = (uint8_t)((hsd->CSD[3] & 0x00010000U) >> 16U);
2120
 
2121
  pCSD->FileFormatGroup = (uint8_t)((hsd->CSD[3] & 0x00008000U) >> 15U);
2122
 
2123
  pCSD->CopyFlag = (uint8_t)((hsd->CSD[3] & 0x00004000U) >> 14U);
2124
 
2125
  pCSD->PermWrProtect = (uint8_t)((hsd->CSD[3] & 0x00002000U) >> 13U);
2126
 
2127
  pCSD->TempWrProtect = (uint8_t)((hsd->CSD[3] & 0x00001000U) >> 12U);
2128
 
2129
  pCSD->FileFormat = (uint8_t)((hsd->CSD[3] & 0x00000C00U) >> 10U);
2130
 
2131
  pCSD->ECC= (uint8_t)((hsd->CSD[3] & 0x00000300U) >> 8U);
2132
 
2133
  pCSD->CSD_CRC = (uint8_t)((hsd->CSD[3] & 0x000000FEU) >> 1U);
2134
 
2135
  pCSD->Reserved4 = 1;
2136
 
2 mjames 2137
  return HAL_OK;
2138
}
2139
 
2140
/**
2141
  * @brief  Gets the SD status info.
9 mjames 2142
  * @param  hsd: Pointer to SD handle
2 mjames 2143
  * @param  pStatus: Pointer to the HAL_SD_CardStatusTypeDef structure that
9 mjames 2144
  *         will contain the SD card status information
2 mjames 2145
  * @retval HAL status
2146
  */
2147
HAL_StatusTypeDef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypeDef *pStatus)
2148
{
9 mjames 2149
  uint32_t sd_status[16];
2150
  uint32_t errorstate;
2151
 
2 mjames 2152
  errorstate = SD_SendSDStatus(hsd, sd_status);
9 mjames 2153
  if(errorstate != HAL_SD_ERROR_NONE)
2 mjames 2154
  {
2155
    /* Clear all the static flags */
9 mjames 2156
    __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2 mjames 2157
    hsd->ErrorCode |= errorstate;
2158
    hsd->State = HAL_SD_STATE_READY;
2159
    return HAL_ERROR;
2160
  }
2161
  else
2162
  {
9 mjames 2163
    pStatus->DataBusWidth = (uint8_t)((sd_status[0] & 0xC0U) >> 6U);
2164
 
2165
    pStatus->SecuredMode = (uint8_t)((sd_status[0] & 0x20U) >> 5U);
2166
 
2167
    pStatus->CardType = (uint16_t)(((sd_status[0] & 0x00FF0000U) >> 8U) | ((sd_status[0] & 0xFF000000U) >> 24U));
2168
 
2169
    pStatus->ProtectedAreaSize = (((sd_status[1] & 0xFFU) << 24U)    | ((sd_status[1] & 0xFF00U) << 8U) |
2170
                                  ((sd_status[1] & 0xFF0000U) >> 8U) | ((sd_status[1] & 0xFF000000U) >> 24U));
2171
 
2172
    pStatus->SpeedClass = (uint8_t)(sd_status[2] & 0xFFU);
2173
 
2174
    pStatus->PerformanceMove = (uint8_t)((sd_status[2] & 0xFF00U) >> 8U);
2175
 
2176
    pStatus->AllocationUnitSize = (uint8_t)((sd_status[2] & 0xF00000U) >> 20U);
2177
 
2178
    pStatus->EraseSize = (uint16_t)(((sd_status[2] & 0xFF000000U) >> 16U) | (sd_status[3] & 0xFFU));
2179
 
2180
    pStatus->EraseTimeout = (uint8_t)((sd_status[3] & 0xFC00U) >> 10U);
2181
 
2182
    pStatus->EraseOffset = (uint8_t)((sd_status[3] & 0x0300U) >> 8U);
2 mjames 2183
  }
9 mjames 2184
 
2 mjames 2185
  return HAL_OK;
2186
}
2187
 
2188
/**
2189
  * @brief  Gets the SD card info.
9 mjames 2190
  * @param  hsd: Pointer to SD handle
2191
  * @param  pCardInfo: Pointer to the HAL_SD_CardInfoTypeDef structure that
2192
  *         will contain the SD card status information
2 mjames 2193
  * @retval HAL status
2194
  */
2195
HAL_StatusTypeDef HAL_SD_GetCardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypeDef *pCardInfo)
2196
{
2197
  pCardInfo->CardType     = (uint32_t)(hsd->SdCard.CardType);
2198
  pCardInfo->CardVersion  = (uint32_t)(hsd->SdCard.CardVersion);
2199
  pCardInfo->Class        = (uint32_t)(hsd->SdCard.Class);
2200
  pCardInfo->RelCardAdd   = (uint32_t)(hsd->SdCard.RelCardAdd);
2201
  pCardInfo->BlockNbr     = (uint32_t)(hsd->SdCard.BlockNbr);
2202
  pCardInfo->BlockSize    = (uint32_t)(hsd->SdCard.BlockSize);
2203
  pCardInfo->LogBlockNbr  = (uint32_t)(hsd->SdCard.LogBlockNbr);
2204
  pCardInfo->LogBlockSize = (uint32_t)(hsd->SdCard.LogBlockSize);
9 mjames 2205
 
2 mjames 2206
  return HAL_OK;
2207
}
2208
 
2209
/**
9 mjames 2210
  * @brief  Enables wide bus operation for the requested card if supported by
2 mjames 2211
  *         card.
9 mjames 2212
  * @param  hsd: Pointer to SD handle
2213
  * @param  WideMode: Specifies the SD card wide bus mode
2 mjames 2214
  *          This parameter can be one of the following values:
2215
  *            @arg SDIO_BUS_WIDE_8B: 8-bit data transfer
2216
  *            @arg SDIO_BUS_WIDE_4B: 4-bit data transfer
2217
  *            @arg SDIO_BUS_WIDE_1B: 1-bit data transfer
2218
  * @retval HAL status
2219
  */
2220
HAL_StatusTypeDef HAL_SD_ConfigWideBusOperation(SD_HandleTypeDef *hsd, uint32_t WideMode)
2221
{
2222
  SDIO_InitTypeDef Init;
9 mjames 2223
  uint32_t errorstate;
2224
 
2 mjames 2225
  /* Check the parameters */
2226
  assert_param(IS_SDIO_BUS_WIDE(WideMode));
9 mjames 2227
 
2228
  /* Change State */
2 mjames 2229
  hsd->State = HAL_SD_STATE_BUSY;
9 mjames 2230
 
2231
  if(hsd->SdCard.CardType != CARD_SECURED)
2 mjames 2232
  {
2233
    if(WideMode == SDIO_BUS_WIDE_8B)
2234
    {
2235
      hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
2236
    }
2237
    else if(WideMode == SDIO_BUS_WIDE_4B)
2238
    {
2239
      errorstate = SD_WideBus_Enable(hsd);
9 mjames 2240
 
2 mjames 2241
      hsd->ErrorCode |= errorstate;
2242
    }
2243
    else if(WideMode == SDIO_BUS_WIDE_1B)
2244
    {
2245
      errorstate = SD_WideBus_Disable(hsd);
9 mjames 2246
 
2 mjames 2247
      hsd->ErrorCode |= errorstate;
2248
    }
2249
    else
2250
    {
2251
      /* WideMode is not a valid argument*/
2252
      hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
2253
    }
9 mjames 2254
  }
2 mjames 2255
  else
2256
  {
2257
    /* MMC Card does not support this feature */
2258
    hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
2259
  }
9 mjames 2260
 
2 mjames 2261
  if(hsd->ErrorCode != HAL_SD_ERROR_NONE)
2262
  {
2263
    /* Clear all the static flags */
2264
    __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2265
    hsd->State = HAL_SD_STATE_READY;
2266
    return HAL_ERROR;
2267
  }
2268
  else
2269
  {
2270
    /* Configure the SDIO peripheral */
2271
    Init.ClockEdge           = hsd->Init.ClockEdge;
2272
    Init.ClockBypass         = hsd->Init.ClockBypass;
2273
    Init.ClockPowerSave      = hsd->Init.ClockPowerSave;
2274
    Init.BusWide             = WideMode;
2275
    Init.HardwareFlowControl = hsd->Init.HardwareFlowControl;
2276
    Init.ClockDiv            = hsd->Init.ClockDiv;
9 mjames 2277
    (void)SDIO_Init(hsd->Instance, Init);
2 mjames 2278
  }
2279
 
2280
  /* Change State */
2281
  hsd->State = HAL_SD_STATE_READY;
9 mjames 2282
 
2 mjames 2283
  return HAL_OK;
2284
}
2285
 
2286
/**
2287
  * @brief  Gets the current sd card data state.
2288
  * @param  hsd: pointer to SD handle
2289
  * @retval Card state
2290
  */
2291
HAL_SD_CardStateTypeDef HAL_SD_GetCardState(SD_HandleTypeDef *hsd)
2292
{
9 mjames 2293
  uint32_t cardstate;
2294
  uint32_t errorstate;
2 mjames 2295
  uint32_t resp1 = 0;
9 mjames 2296
 
2 mjames 2297
  errorstate = SD_SendStatus(hsd, &resp1);
9 mjames 2298
  if(errorstate != HAL_SD_ERROR_NONE)
2 mjames 2299
  {
2300
    hsd->ErrorCode |= errorstate;
2301
  }
2302
 
9 mjames 2303
  cardstate = ((resp1 >> 9U) & 0x0FU);
2304
 
2305
  return (HAL_SD_CardStateTypeDef)cardstate;
2 mjames 2306
}
2307
 
2308
/**
2309
  * @brief  Abort the current transfer and disable the SD.
2310
  * @param  hsd: pointer to a SD_HandleTypeDef structure that contains
2311
  *                the configuration information for SD module.
2312
  * @retval HAL status
2313
  */
2314
HAL_StatusTypeDef HAL_SD_Abort(SD_HandleTypeDef *hsd)
2315
{
2316
  HAL_SD_CardStateTypeDef CardState;
9 mjames 2317
  uint32_t context = hsd->Context;
2318
 
2 mjames 2319
  /* DIsable All interrupts */
2320
  __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2321
                           SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
9 mjames 2322
 
2 mjames 2323
  /* Clear All flags */
9 mjames 2324
  __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
2325
 
2326
  CLEAR_BIT(hsd->Instance->DCTRL, SDIO_DCTRL_DTEN);
2327
 
2328
  if ((context & SD_CONTEXT_DMA) != 0U)
2 mjames 2329
  {
2330
    /* Disable the SD DMA request */
2331
    hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
9 mjames 2332
 
2333
    /* Abort the SD DMA Tx channel */
2334
    if (((context & SD_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
2 mjames 2335
    {
9 mjames 2336
      if(HAL_DMA_Abort(hsd->hdmatx) != HAL_OK)
2337
      {
2338
        hsd->ErrorCode |= HAL_SD_ERROR_DMA;
2339
      }
2 mjames 2340
    }
9 mjames 2341
    /* Abort the SD DMA Rx channel */
2342
    else if (((context & SD_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
2 mjames 2343
    {
9 mjames 2344
      if(HAL_DMA_Abort(hsd->hdmarx) != HAL_OK)
2345
      {
2346
        hsd->ErrorCode |= HAL_SD_ERROR_DMA;
2347
      }
2 mjames 2348
    }
9 mjames 2349
    else
2350
    {
2351
      /* Nothing to do */
2352
    }
2 mjames 2353
  }
9 mjames 2354
 
2 mjames 2355
  hsd->State = HAL_SD_STATE_READY;
9 mjames 2356
 
2357
  /* Initialize the SD operation */
2358
  hsd->Context = SD_CONTEXT_NONE;
2359
 
2 mjames 2360
  CardState = HAL_SD_GetCardState(hsd);
2361
  if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
2362
  {
2363
    hsd->ErrorCode = SDMMC_CmdStopTransfer(hsd->Instance);
2364
  }
2365
  if(hsd->ErrorCode != HAL_SD_ERROR_NONE)
2366
  {
2367
    return HAL_ERROR;
2368
  }
2369
  return HAL_OK;
2370
}
2371
 
2372
/**
2373
  * @brief  Abort the current transfer and disable the SD (IT mode).
2374
  * @param  hsd: pointer to a SD_HandleTypeDef structure that contains
2375
  *                the configuration information for SD module.
2376
  * @retval HAL status
2377
  */
2378
HAL_StatusTypeDef HAL_SD_Abort_IT(SD_HandleTypeDef *hsd)
2379
{
2380
  HAL_SD_CardStateTypeDef CardState;
9 mjames 2381
  uint32_t context = hsd->Context;
2382
 
2383
  /* Disable All interrupts */
2 mjames 2384
  __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2385
                           SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
9 mjames 2386
 
2387
  CLEAR_BIT(hsd->Instance->DCTRL, SDIO_DCTRL_DTEN);
2388
 
2389
  if ((context & SD_CONTEXT_DMA) != 0U)
2 mjames 2390
  {
2391
    /* Disable the SD DMA request */
2392
    hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
9 mjames 2393
 
2394
    /* Abort the SD DMA Tx channel */
2395
    if (((context & SD_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
2 mjames 2396
    {
9 mjames 2397
      hsd->hdmatx->XferAbortCallback = SD_DMATxAbort;
2 mjames 2398
      if(HAL_DMA_Abort_IT(hsd->hdmatx) != HAL_OK)
2399
      {
2400
        hsd->hdmatx = NULL;
2401
      }
2402
    }
9 mjames 2403
    /* Abort the SD DMA Rx channel */
2404
    else if (((context & SD_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
2 mjames 2405
    {
9 mjames 2406
      hsd->hdmarx->XferAbortCallback = SD_DMARxAbort;
2 mjames 2407
      if(HAL_DMA_Abort_IT(hsd->hdmarx) != HAL_OK)
2408
      {
2409
        hsd->hdmarx = NULL;
2410
      }
2411
    }
9 mjames 2412
    else
2413
    {
2414
      /* Nothing to do */
2415
    }
2 mjames 2416
  }
2417
  /* No transfer ongoing on both DMA channels*/
9 mjames 2418
  else
2 mjames 2419
  {
9 mjames 2420
    /* Clear All flags */
2421
    __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
2422
 
2 mjames 2423
    CardState = HAL_SD_GetCardState(hsd);
2424
    hsd->State = HAL_SD_STATE_READY;
9 mjames 2425
    hsd->Context = SD_CONTEXT_NONE;
2 mjames 2426
    if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
2427
    {
2428
      hsd->ErrorCode = SDMMC_CmdStopTransfer(hsd->Instance);
2429
    }
2430
    if(hsd->ErrorCode != HAL_SD_ERROR_NONE)
2431
    {
2432
      return HAL_ERROR;
2433
    }
2434
    else
2435
    {
9 mjames 2436
#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)
2437
      hsd->AbortCpltCallback(hsd);
2438
#else
2 mjames 2439
      HAL_SD_AbortCallback(hsd);
9 mjames 2440
#endif /* USE_HAL_SD_REGISTER_CALLBACKS */
2 mjames 2441
    }
2442
  }
9 mjames 2443
 
2 mjames 2444
  return HAL_OK;
2445
}
2446
 
2447
/**
2448
  * @}
2449
  */
9 mjames 2450
 
2 mjames 2451
/**
2452
  * @}
2453
  */
9 mjames 2454
 
2455
/* Private function ----------------------------------------------------------*/
2 mjames 2456
/** @addtogroup SD_Private_Functions
2457
  * @{
2458
  */
2459
 
2460
/**
9 mjames 2461
  * @brief  DMA SD transmit process complete callback
2 mjames 2462
  * @param  hdma: DMA handle
2463
  * @retval None
2464
  */
9 mjames 2465
static void SD_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2 mjames 2466
{
2467
  SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
9 mjames 2468
 
2 mjames 2469
  /* Enable DATAEND Interrupt */
2470
  __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DATAEND));
2471
}
2472
 
2473
/**
9 mjames 2474
  * @brief  DMA SD receive process complete callback
2 mjames 2475
  * @param  hdma: DMA handle
2476
  * @retval None
2477
  */
9 mjames 2478
static void SD_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2 mjames 2479
{
2480
  SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
9 mjames 2481
  uint32_t errorstate;
2482
 
2 mjames 2483
  /* Send stop command in multiblock write */
2484
  if(hsd->Context == (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA))
2485
  {
2486
    errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
2487
    if(errorstate != HAL_SD_ERROR_NONE)
2488
    {
2489
      hsd->ErrorCode |= errorstate;
9 mjames 2490
#if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
2491
      hsd->ErrorCallback(hsd);
2492
#else
2 mjames 2493
      HAL_SD_ErrorCallback(hsd);
9 mjames 2494
#endif
2 mjames 2495
    }
2496
  }
9 mjames 2497
 
2 mjames 2498
  /* Disable the DMA transfer for transmit request by setting the DMAEN bit
2499
  in the SD DCTRL register */
2500
  hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
9 mjames 2501
 
2 mjames 2502
  /* Clear all the static flags */
9 mjames 2503
  __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
2504
 
2 mjames 2505
  hsd->State = HAL_SD_STATE_READY;
9 mjames 2506
  hsd->Context = SD_CONTEXT_NONE;
2 mjames 2507
 
9 mjames 2508
#if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
2509
  hsd->RxCpltCallback(hsd);
2510
#else
2 mjames 2511
  HAL_SD_RxCpltCallback(hsd);
9 mjames 2512
#endif
2 mjames 2513
}
2514
 
2515
/**
9 mjames 2516
  * @brief  DMA SD communication error callback
2 mjames 2517
  * @param  hdma: DMA handle
2518
  * @retval None
2519
  */
9 mjames 2520
static void SD_DMAError(DMA_HandleTypeDef *hdma)
2 mjames 2521
{
2522
  SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
2523
  HAL_SD_CardStateTypeDef CardState;
9 mjames 2524
  uint32_t RxErrorCode, TxErrorCode;
2525
 
2526
    RxErrorCode = hsd->hdmarx->ErrorCode;
2527
    TxErrorCode = hsd->hdmatx->ErrorCode;  
2528
    if((RxErrorCode == HAL_DMA_ERROR_TE) || (TxErrorCode == HAL_DMA_ERROR_TE))
2 mjames 2529
    {
9 mjames 2530
      /* Clear All flags */
2531
      __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
2532
 
2533
      /* Disable All interrupts */
2534
      __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2535
        SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
2536
 
2537
      hsd->ErrorCode |= HAL_SD_ERROR_DMA;
2538
      CardState = HAL_SD_GetCardState(hsd);
2539
      if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
2540
      {
2541
        hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance);
2542
      }
2543
 
2544
      hsd->State= HAL_SD_STATE_READY;
2545
      hsd->Context = SD_CONTEXT_NONE;
2 mjames 2546
    }
2547
 
9 mjames 2548
#if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
2549
    hsd->ErrorCallback(hsd);
2550
#else
2551
    HAL_SD_ErrorCallback(hsd);
2552
#endif
2 mjames 2553
}
2554
 
2555
/**
9 mjames 2556
  * @brief  DMA SD Tx Abort callback
2 mjames 2557
  * @param  hdma: DMA handle
2558
  * @retval None
2559
  */
9 mjames 2560
static void SD_DMATxAbort(DMA_HandleTypeDef *hdma)
2 mjames 2561
{
2562
  SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
2563
  HAL_SD_CardStateTypeDef CardState;
9 mjames 2564
 
2565
  /* Clear All flags */
2566
  __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
2567
 
2568
  CardState = HAL_SD_GetCardState(hsd);
2569
  hsd->State = HAL_SD_STATE_READY;
2570
  hsd->Context = SD_CONTEXT_NONE;
2571
  if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
2 mjames 2572
  {
9 mjames 2573
    hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance);
2 mjames 2574
  }
9 mjames 2575
 
2576
  if(hsd->ErrorCode == HAL_SD_ERROR_NONE)
2 mjames 2577
  {
9 mjames 2578
#if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
2579
    hsd->AbortCpltCallback(hsd);
2580
#else
2581
    HAL_SD_AbortCallback(hsd);
2582
#endif
2 mjames 2583
  }
9 mjames 2584
  else
2585
  {
2586
#if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
2587
    hsd->ErrorCallback(hsd);
2588
#else
2589
    HAL_SD_ErrorCallback(hsd);
2590
#endif
2591
  }
2 mjames 2592
}
2593
 
2594
/**
9 mjames 2595
  * @brief  DMA SD Rx Abort callback
2 mjames 2596
  * @param  hdma: DMA handle
2597
  * @retval None
2598
  */
9 mjames 2599
static void SD_DMARxAbort(DMA_HandleTypeDef *hdma)
2 mjames 2600
{
2601
  SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
2602
  HAL_SD_CardStateTypeDef CardState;
9 mjames 2603
 
2604
  /* Clear All flags */
2605
  __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
2606
 
2607
  CardState = HAL_SD_GetCardState(hsd);
2608
  hsd->State = HAL_SD_STATE_READY;
2609
  hsd->Context = SD_CONTEXT_NONE;
2610
  if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
2 mjames 2611
  {
9 mjames 2612
    hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance);
2 mjames 2613
  }
9 mjames 2614
 
2615
  if(hsd->ErrorCode == HAL_SD_ERROR_NONE)
2 mjames 2616
  {
9 mjames 2617
#if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
2618
    hsd->AbortCpltCallback(hsd);
2619
#else
2620
    HAL_SD_AbortCallback(hsd);
2621
#endif
2 mjames 2622
  }
9 mjames 2623
  else
2624
  {
2625
#if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
2626
    hsd->ErrorCallback(hsd);
2627
#else
2628
    HAL_SD_ErrorCallback(hsd);
2629
#endif
2630
  }
2 mjames 2631
}
2632
 
2633
/**
2634
  * @brief  Initializes the sd card.
2635
  * @param  hsd: Pointer to SD handle
2636
  * @retval SD Card error state
2637
  */
2638
static uint32_t SD_InitCard(SD_HandleTypeDef *hsd)
2639
{
2640
  HAL_SD_CardCSDTypeDef CSD;
9 mjames 2641
  uint32_t errorstate;
2 mjames 2642
  uint16_t sd_rca = 1U;
9 mjames 2643
 
2 mjames 2644
  /* Check the power State */
9 mjames 2645
  if(SDIO_GetPowerState(hsd->Instance) == 0U)
2 mjames 2646
  {
2647
    /* Power off */
2648
    return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
2649
  }
9 mjames 2650
 
2651
  if(hsd->SdCard.CardType != CARD_SECURED)
2 mjames 2652
  {
2653
    /* Send CMD2 ALL_SEND_CID */
2654
    errorstate = SDMMC_CmdSendCID(hsd->Instance);
2655
    if(errorstate != HAL_SD_ERROR_NONE)
2656
    {
2657
      return errorstate;
2658
    }
2659
    else
2660
    {
2661
      /* Get Card identification number data */
2662
      hsd->CID[0U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
2663
      hsd->CID[1U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP2);
2664
      hsd->CID[2U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP3);
2665
      hsd->CID[3U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP4);
2666
    }
2667
  }
9 mjames 2668
 
2669
  if(hsd->SdCard.CardType != CARD_SECURED)
2 mjames 2670
  {
2671
    /* Send CMD3 SET_REL_ADDR with argument 0 */
2672
    /* SD Card publishes its RCA. */
2673
    errorstate = SDMMC_CmdSetRelAdd(hsd->Instance, &sd_rca);
2674
    if(errorstate != HAL_SD_ERROR_NONE)
2675
    {
2676
      return errorstate;
2677
    }
2678
  }
9 mjames 2679
  if(hsd->SdCard.CardType != CARD_SECURED)
2 mjames 2680
  {
2681
    /* Get the SD card RCA */
2682
    hsd->SdCard.RelCardAdd = sd_rca;
9 mjames 2683
 
2 mjames 2684
    /* Send CMD9 SEND_CSD with argument as card's RCA */
2685
    errorstate = SDMMC_CmdSendCSD(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
2686
    if(errorstate != HAL_SD_ERROR_NONE)
2687
    {
2688
      return errorstate;
2689
    }
2690
    else
2691
    {
2692
      /* Get Card Specific Data */
2693
      hsd->CSD[0U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
2694
      hsd->CSD[1U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP2);
2695
      hsd->CSD[2U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP3);
2696
      hsd->CSD[3U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP4);
2697
    }
2698
  }
9 mjames 2699
 
2 mjames 2700
  /* Get the Card Class */
2701
  hsd->SdCard.Class = (SDIO_GetResponse(hsd->Instance, SDIO_RESP2) >> 20U);
9 mjames 2702
 
2 mjames 2703
  /* Get CSD parameters */
9 mjames 2704
  if (HAL_SD_GetCardCSD(hsd, &CSD) != HAL_OK)
2705
  {
2706
    return HAL_SD_ERROR_UNSUPPORTED_FEATURE;
2707
  }
2 mjames 2708
 
2709
  /* Select the Card */
2710
  errorstate = SDMMC_CmdSelDesel(hsd->Instance, (uint32_t)(((uint32_t)hsd->SdCard.RelCardAdd) << 16U));
2711
  if(errorstate != HAL_SD_ERROR_NONE)
2712
  {
2713
    return errorstate;
2714
  }
2715
 
9 mjames 2716
  /* Configure SDIO peripheral interface */
2717
  (void)SDIO_Init(hsd->Instance, hsd->Init);
2 mjames 2718
 
2719
  /* All cards are initialized */
2720
  return HAL_SD_ERROR_NONE;
2721
}
2722
 
2723
/**
2724
  * @brief  Enquires cards about their operating voltage and configures clock
2725
  *         controls and stores SD information that will be needed in future
2726
  *         in the SD handle.
2727
  * @param  hsd: Pointer to SD handle
2728
  * @retval error state
2729
  */
2730
static uint32_t SD_PowerON(SD_HandleTypeDef *hsd)
2731
{
2732
  __IO uint32_t count = 0U;
2733
  uint32_t response = 0U, validvoltage = 0U;
9 mjames 2734
  uint32_t errorstate;
2735
 
2 mjames 2736
  /* CMD0: GO_IDLE_STATE */
2737
  errorstate = SDMMC_CmdGoIdleState(hsd->Instance);
2738
  if(errorstate != HAL_SD_ERROR_NONE)
2739
  {
2740
    return errorstate;
2741
  }
9 mjames 2742
 
2 mjames 2743
  /* CMD8: SEND_IF_COND: Command available only on V2.0 cards */
2744
  errorstate = SDMMC_CmdOperCond(hsd->Instance);
2745
  if(errorstate != HAL_SD_ERROR_NONE)
2746
  {
2747
    hsd->SdCard.CardVersion = CARD_V1_X;
9 mjames 2748
    /* CMD0: GO_IDLE_STATE */
2749
    errorstate = SDMMC_CmdGoIdleState(hsd->Instance);
2750
    if(errorstate != HAL_SD_ERROR_NONE)
2 mjames 2751
    {
9 mjames 2752
      return errorstate;
2 mjames 2753
    }
9 mjames 2754
 
2 mjames 2755
  }
2756
  else
2757
  {
2758
    hsd->SdCard.CardVersion = CARD_V2_X;
9 mjames 2759
  }
2760
 
2761
  if( hsd->SdCard.CardVersion == CARD_V2_X)
2762
  {
2763
    /* SEND CMD55 APP_CMD with RCA as 0 */
2764
    errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0);
2765
    if(errorstate != HAL_SD_ERROR_NONE)
2 mjames 2766
    {
9 mjames 2767
      return HAL_SD_ERROR_UNSUPPORTED_FEATURE;
2 mjames 2768
    }
9 mjames 2769
  }
2770
  /* SD CARD */
2771
  /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */
2772
  while((count < SDMMC_MAX_VOLT_TRIAL) && (validvoltage == 0U))
2773
  {
2774
    /* SEND CMD55 APP_CMD with RCA as 0 */
2775
    errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0);
2776
    if(errorstate != HAL_SD_ERROR_NONE)
2 mjames 2777
    {
9 mjames 2778
      return errorstate;
2 mjames 2779
    }
9 mjames 2780
 
2781
    /* Send CMD41 */
2782
    errorstate = SDMMC_CmdAppOperCommand(hsd->Instance, SDMMC_VOLTAGE_WINDOW_SD | SDMMC_HIGH_CAPACITY | SD_SWITCH_1_8V_CAPACITY);
2783
    if(errorstate != HAL_SD_ERROR_NONE)
2 mjames 2784
    {
9 mjames 2785
      return HAL_SD_ERROR_UNSUPPORTED_FEATURE;
2 mjames 2786
    }
9 mjames 2787
 
2788
    /* Get command response */
2789
    response = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
2790
 
2791
    /* Get operating voltage*/
2792
    validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
2793
 
2794
    count++;
2 mjames 2795
  }
9 mjames 2796
 
2797
  if(count >= SDMMC_MAX_VOLT_TRIAL)
2798
  {
2799
    return HAL_SD_ERROR_INVALID_VOLTRANGE;
2800
  }
2801
 
2802
  if((response & SDMMC_HIGH_CAPACITY) == SDMMC_HIGH_CAPACITY) /* (response &= SD_HIGH_CAPACITY) */
2803
  {
2804
    hsd->SdCard.CardType = CARD_SDHC_SDXC;
2805
  }
2806
  else
2807
  {
2808
    hsd->SdCard.CardType = CARD_SDSC;
2809
  }
2810
 
2811
 
2 mjames 2812
  return HAL_SD_ERROR_NONE;
2813
}
2814
 
2815
/**
2816
  * @brief  Turns the SDIO output signals off.
2817
  * @param  hsd: Pointer to SD handle
9 mjames 2818
  * @retval None
2 mjames 2819
  */
9 mjames 2820
static void SD_PowerOFF(SD_HandleTypeDef *hsd)
2 mjames 2821
{
2822
  /* Set Power State to OFF */
9 mjames 2823
  (void)SDIO_PowerState_OFF(hsd->Instance);
2 mjames 2824
}
2825
 
2826
/**
2827
  * @brief  Send Status info command.
2828
  * @param  hsd: pointer to SD handle
9 mjames 2829
  * @param  pSDstatus: Pointer to the buffer that will contain the SD card status
2 mjames 2830
  *         SD Status register)
2831
  * @retval error state
2832
  */
2833
static uint32_t SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus)
2834
{
2835
  SDIO_DataInitTypeDef config;
9 mjames 2836
  uint32_t errorstate;
2 mjames 2837
  uint32_t tickstart = HAL_GetTick();
9 mjames 2838
  uint32_t count;
2839
  uint32_t *pData = pSDstatus;
2840
 
2 mjames 2841
  /* Check SD response */
2842
  if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
2843
  {
2844
    return HAL_SD_ERROR_LOCK_UNLOCK_FAILED;
2845
  }
9 mjames 2846
 
2 mjames 2847
  /* Set block size for card if it is not equal to current block size for card */
2848
  errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64U);
2849
  if(errorstate != HAL_SD_ERROR_NONE)
2850
  {
2851
    hsd->ErrorCode |= HAL_SD_ERROR_NONE;
2852
    return errorstate;
2853
  }
9 mjames 2854
 
2 mjames 2855
  /* Send CMD55 */
2856
  errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
2857
  if(errorstate != HAL_SD_ERROR_NONE)
2858
  {
2859
    hsd->ErrorCode |= HAL_SD_ERROR_NONE;
2860
    return errorstate;
2861
  }
9 mjames 2862
 
2863
  /* Configure the SD DPSM (Data Path State Machine) */
2 mjames 2864
  config.DataTimeOut   = SDMMC_DATATIMEOUT;
2865
  config.DataLength    = 64U;
2866
  config.DataBlockSize = SDIO_DATABLOCK_SIZE_64B;
2867
  config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
2868
  config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
2869
  config.DPSM          = SDIO_DPSM_ENABLE;
9 mjames 2870
  (void)SDIO_ConfigData(hsd->Instance, &config);
2871
 
2 mjames 2872
  /* Send ACMD13 (SD_APP_STAUS)  with argument as card's RCA */
2873
  errorstate = SDMMC_CmdStatusRegister(hsd->Instance);
2874
  if(errorstate != HAL_SD_ERROR_NONE)
2875
  {
2876
    hsd->ErrorCode |= HAL_SD_ERROR_NONE;
2877
    return errorstate;
2878
  }
9 mjames 2879
 
2 mjames 2880
  /* Get status data */
2881
  while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND))
2882
  {
2883
    if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF))
2884
    {
2885
      for(count = 0U; count < 8U; count++)
2886
      {
9 mjames 2887
        *pData = SDIO_ReadFIFO(hsd->Instance);
2888
        pData++;
2 mjames 2889
      }
2890
    }
9 mjames 2891
 
2 mjames 2892
    if((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
2893
    {
2894
      return HAL_SD_ERROR_TIMEOUT;
2895
    }
2896
  }
9 mjames 2897
 
2 mjames 2898
  if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
2899
  {
2900
    return HAL_SD_ERROR_DATA_TIMEOUT;
2901
  }
2902
  else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
2903
  {
2904
    return HAL_SD_ERROR_DATA_CRC_FAIL;
2905
  }
2906
  else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
2907
  {
2908
    return HAL_SD_ERROR_RX_OVERRUN;
2909
  }
9 mjames 2910
  else
2911
  {
2912
    /* Nothing to do */
2913
  }
2 mjames 2914
 
2915
  while ((__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)))
2916
  {
9 mjames 2917
    *pData = SDIO_ReadFIFO(hsd->Instance);
2918
    pData++;
2919
 
2 mjames 2920
    if((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
2921
    {
2922
      return HAL_SD_ERROR_TIMEOUT;
2923
    }
2924
  }
9 mjames 2925
 
2 mjames 2926
  /* Clear all the static status flags*/
9 mjames 2927
  __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
2928
 
2 mjames 2929
  return HAL_SD_ERROR_NONE;
2930
}
2931
 
2932
/**
2933
  * @brief  Returns the current card's status.
2934
  * @param  hsd: Pointer to SD handle
9 mjames 2935
  * @param  pCardStatus: pointer to the buffer that will contain the SD card
2936
  *         status (Card Status register)
2 mjames 2937
  * @retval error state
2938
  */
2939
static uint32_t SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus)
2940
{
9 mjames 2941
  uint32_t errorstate;
2942
 
2 mjames 2943
  if(pCardStatus == NULL)
2944
  {
2945
    return HAL_SD_ERROR_PARAM;
2946
  }
9 mjames 2947
 
2 mjames 2948
  /* Send Status command */
2949
  errorstate = SDMMC_CmdSendStatus(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
9 mjames 2950
  if(errorstate != HAL_SD_ERROR_NONE)
2 mjames 2951
  {
2952
    return errorstate;
2953
  }
9 mjames 2954
 
2 mjames 2955
  /* Get SD card status */
2956
  *pCardStatus = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
9 mjames 2957
 
2 mjames 2958
  return HAL_SD_ERROR_NONE;
2959
}
2960
 
2961
/**
2962
  * @brief  Enables the SDIO wide bus mode.
2963
  * @param  hsd: pointer to SD handle
2964
  * @retval error state
2965
  */
2966
static uint32_t SD_WideBus_Enable(SD_HandleTypeDef *hsd)
2967
{
2968
  uint32_t scr[2U] = {0U, 0U};
9 mjames 2969
  uint32_t errorstate;
2970
 
2 mjames 2971
  if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
2972
  {
2973
    return HAL_SD_ERROR_LOCK_UNLOCK_FAILED;
2974
  }
9 mjames 2975
 
2 mjames 2976
  /* Get SCR Register */
2977
  errorstate = SD_FindSCR(hsd, scr);
9 mjames 2978
  if(errorstate != HAL_SD_ERROR_NONE)
2 mjames 2979
  {
2980
    return errorstate;
2981
  }
9 mjames 2982
 
2 mjames 2983
  /* If requested card supports wide bus operation */
2984
  if((scr[1U] & SDMMC_WIDE_BUS_SUPPORT) != SDMMC_ALLZERO)
2985
  {
2986
    /* Send CMD55 APP_CMD with argument as card's RCA.*/
2987
    errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
9 mjames 2988
    if(errorstate != HAL_SD_ERROR_NONE)
2 mjames 2989
    {
2990
      return errorstate;
2991
    }
9 mjames 2992
 
2 mjames 2993
    /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */
2994
    errorstate = SDMMC_CmdBusWidth(hsd->Instance, 2U);
9 mjames 2995
    if(errorstate != HAL_SD_ERROR_NONE)
2 mjames 2996
    {
2997
      return errorstate;
2998
    }
2999
 
3000
    return HAL_SD_ERROR_NONE;
3001
  }
3002
  else
3003
  {
3004
    return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
3005
  }
3006
}
3007
 
3008
/**
3009
  * @brief  Disables the SDIO wide bus mode.
3010
  * @param  hsd: Pointer to SD handle
3011
  * @retval error state
3012
  */
3013
static uint32_t SD_WideBus_Disable(SD_HandleTypeDef *hsd)
3014
{
3015
  uint32_t scr[2U] = {0U, 0U};
9 mjames 3016
  uint32_t errorstate;
3017
 
2 mjames 3018
  if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
3019
  {
3020
    return HAL_SD_ERROR_LOCK_UNLOCK_FAILED;
3021
  }
9 mjames 3022
 
2 mjames 3023
  /* Get SCR Register */
3024
  errorstate = SD_FindSCR(hsd, scr);
9 mjames 3025
  if(errorstate != HAL_SD_ERROR_NONE)
2 mjames 3026
  {
3027
    return errorstate;
3028
  }
9 mjames 3029
 
2 mjames 3030
  /* If requested card supports 1 bit mode operation */
3031
  if((scr[1U] & SDMMC_SINGLE_BUS_SUPPORT) != SDMMC_ALLZERO)
3032
  {
3033
    /* Send CMD55 APP_CMD with argument as card's RCA */
3034
    errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
9 mjames 3035
    if(errorstate != HAL_SD_ERROR_NONE)
2 mjames 3036
    {
3037
      return errorstate;
3038
    }
9 mjames 3039
 
2 mjames 3040
    /* Send ACMD6 APP_CMD with argument as 0 for single bus mode */
3041
    errorstate = SDMMC_CmdBusWidth(hsd->Instance, 0U);
9 mjames 3042
    if(errorstate != HAL_SD_ERROR_NONE)
2 mjames 3043
    {
3044
      return errorstate;
3045
    }
9 mjames 3046
 
2 mjames 3047
    return HAL_SD_ERROR_NONE;
3048
  }
3049
  else
3050
  {
3051
    return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
3052
  }
3053
}
9 mjames 3054
 
3055
 
2 mjames 3056
/**
3057
  * @brief  Finds the SD card SCR register value.
3058
  * @param  hsd: Pointer to SD handle
9 mjames 3059
  * @param  pSCR: pointer to the buffer that will contain the SCR value
2 mjames 3060
  * @retval error state
3061
  */
3062
static uint32_t SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR)
3063
{
3064
  SDIO_DataInitTypeDef config;
9 mjames 3065
  uint32_t errorstate;
2 mjames 3066
  uint32_t tickstart = HAL_GetTick();
3067
  uint32_t index = 0U;
3068
  uint32_t tempscr[2U] = {0U, 0U};
9 mjames 3069
  uint32_t *scr = pSCR;
3070
 
2 mjames 3071
  /* Set Block Size To 8 Bytes */
3072
  errorstate = SDMMC_CmdBlockLength(hsd->Instance, 8U);
9 mjames 3073
  if(errorstate != HAL_SD_ERROR_NONE)
2 mjames 3074
  {
3075
    return errorstate;
3076
  }
3077
 
3078
  /* Send CMD55 APP_CMD with argument as card's RCA */
3079
  errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)((hsd->SdCard.RelCardAdd) << 16U));
9 mjames 3080
  if(errorstate != HAL_SD_ERROR_NONE)
2 mjames 3081
  {
3082
    return errorstate;
3083
  }
3084
 
3085
  config.DataTimeOut   = SDMMC_DATATIMEOUT;
3086
  config.DataLength    = 8U;
3087
  config.DataBlockSize = SDIO_DATABLOCK_SIZE_8B;
3088
  config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
3089
  config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
3090
  config.DPSM          = SDIO_DPSM_ENABLE;
9 mjames 3091
  (void)SDIO_ConfigData(hsd->Instance, &config);
3092
 
2 mjames 3093
  /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */
3094
  errorstate = SDMMC_CmdSendSCR(hsd->Instance);
9 mjames 3095
  if(errorstate != HAL_SD_ERROR_NONE)
2 mjames 3096
  {
3097
    return errorstate;
3098
  }
9 mjames 3099
 
2 mjames 3100
  while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND))
3101
  {
3102
    if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXDAVL))
3103
    {
3104
      *(tempscr + index) = SDIO_ReadFIFO(hsd->Instance);
3105
      index++;
3106
    }
9 mjames 3107
 
2 mjames 3108
    if((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
3109
    {
3110
      return HAL_SD_ERROR_TIMEOUT;
3111
    }
3112
  }
9 mjames 3113
 
2 mjames 3114
  if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
3115
  {
3116
    __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);
9 mjames 3117
 
2 mjames 3118
    return HAL_SD_ERROR_DATA_TIMEOUT;
3119
  }
3120
  else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
3121
  {
3122
    __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);
9 mjames 3123
 
2 mjames 3124
    return HAL_SD_ERROR_DATA_CRC_FAIL;
3125
  }
3126
  else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
3127
  {
3128
    __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR);
9 mjames 3129
 
2 mjames 3130
    return HAL_SD_ERROR_RX_OVERRUN;
3131
  }
3132
  else
3133
  {
3134
    /* No error flag set */
3135
    /* Clear all the static flags */
9 mjames 3136
    __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_DATA_FLAGS);
3137
 
3138
    *scr = (((tempscr[1] & SDMMC_0TO7BITS) << 24)  | ((tempscr[1] & SDMMC_8TO15BITS) << 8) |\
3139
            ((tempscr[1] & SDMMC_16TO23BITS) >> 8) | ((tempscr[1] & SDMMC_24TO31BITS) >> 24));
3140
    scr++;
3141
    *scr = (((tempscr[0] & SDMMC_0TO7BITS) << 24)  | ((tempscr[0] & SDMMC_8TO15BITS) << 8) |\
3142
            ((tempscr[0] & SDMMC_16TO23BITS) >> 8) | ((tempscr[0] & SDMMC_24TO31BITS) >> 24));
3143
 
2 mjames 3144
  }
3145
 
3146
  return HAL_SD_ERROR_NONE;
3147
}
3148
 
3149
/**
3150
  * @brief  Wrap up reading in non-blocking mode.
3151
  * @param  hsd: pointer to a SD_HandleTypeDef structure that contains
3152
  *              the configuration information.
9 mjames 3153
  * @retval None
2 mjames 3154
  */
9 mjames 3155
static void SD_Read_IT(SD_HandleTypeDef *hsd)
2 mjames 3156
{
9 mjames 3157
  uint32_t count, data, dataremaining;
3158
  uint8_t* tmp;
2 mjames 3159
 
9 mjames 3160
  tmp = hsd->pRxBuffPtr;
3161
  dataremaining = hsd->RxXferSize;
3162
 
3163
  if (dataremaining > 0U)
2 mjames 3164
  {
9 mjames 3165
    /* Read data from SDIO Rx FIFO */
3166
    for(count = 0U; count < 8U; count++)
3167
    {
3168
      data = SDIO_ReadFIFO(hsd->Instance);
3169
      *tmp = (uint8_t)(data & 0xFFU);
3170
      tmp++;
3171
      dataremaining--;
3172
      *tmp = (uint8_t)((data >> 8U) & 0xFFU);
3173
      tmp++;
3174
      dataremaining--;
3175
      *tmp = (uint8_t)((data >> 16U) & 0xFFU);
3176
      tmp++;
3177
      dataremaining--;
3178
      *tmp = (uint8_t)((data >> 24U) & 0xFFU);
3179
      tmp++;
3180
      dataremaining--;
3181
    }
3182
 
3183
    hsd->pRxBuffPtr = tmp;
3184
    hsd->RxXferSize = dataremaining;
2 mjames 3185
  }
3186
}
3187
 
3188
/**
3189
  * @brief  Wrap up writing in non-blocking mode.
3190
  * @param  hsd: pointer to a SD_HandleTypeDef structure that contains
3191
  *              the configuration information.
9 mjames 3192
  * @retval None
2 mjames 3193
  */
9 mjames 3194
static void SD_Write_IT(SD_HandleTypeDef *hsd)
2 mjames 3195
{
9 mjames 3196
  uint32_t count, data, dataremaining;
3197
  uint8_t* tmp;
3198
 
3199
  tmp = hsd->pTxBuffPtr;
3200
  dataremaining = hsd->TxXferSize;
3201
 
3202
  if (dataremaining > 0U)
2 mjames 3203
  {
9 mjames 3204
    /* Write data to SDIO Tx FIFO */
3205
    for(count = 0U; count < 8U; count++)
3206
    {
3207
      data = (uint32_t)(*tmp);
3208
      tmp++;
3209
      dataremaining--;
3210
      data |= ((uint32_t)(*tmp) << 8U);
3211
      tmp++;
3212
      dataremaining--;
3213
      data |= ((uint32_t)(*tmp) << 16U);
3214
      tmp++;
3215
      dataremaining--;
3216
      data |= ((uint32_t)(*tmp) << 24U);
3217
      tmp++;
3218
      dataremaining--;
3219
      (void)SDIO_WriteFIFO(hsd->Instance, &data);
3220
    }
3221
 
3222
    hsd->pTxBuffPtr = tmp;
3223
    hsd->TxXferSize = dataremaining;
2 mjames 3224
  }
3225
}
3226
 
3227
/**
3228
  * @}
3229
  */
3230
 
3231
#endif /* HAL_SD_MODULE_ENABLED */
3232
 
3233
/**
3234
  * @}
3235
  */
3236
 
3237
/**
3238
  * @}
3239
  */
3240
 
9 mjames 3241
#endif /* SDIO */
3242
 
2 mjames 3243
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/