Subversion Repositories canSerial

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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