1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_dma_ex.c
4 * @author MCD Application Team
5 * @brief DMA Extension HAL module driver
6 * This file provides firmware functions to manage the following
7 * functionalities of the DMA Extension peripheral:
8 * + Extended features functions
9 *
10 @verbatim
11 ==============================================================================
12 ##### How to use this driver #####
13 ==============================================================================
14 [..]
15 The DMA Extension HAL driver can be used as follows:
16 (+) Start a multi buffer transfer using the HAL_DMA_MultiBufferStart() function
17 for polling mode or HAL_DMA_MultiBufferStart_IT() for interrupt mode.
18
19 -@- In Memory-to-Memory transfer mode, Multi (Double) Buffer mode is not allowed.
20 -@- When Multi (Double) Buffer mode is enabled, the transfer is circular by default.
21 -@- In Multi (Double) buffer mode, it is possible to update the base address for
22 the AHB memory port on the fly (DMA_SxM0AR or DMA_SxM1AR) when the stream is enabled.
23
24 @endverbatim
25 ******************************************************************************
26 * @attention
27 *
28 * <h2><center>© Copyright (c) 2017 STMicroelectronics.
29 * All rights reserved.</center></h2>
30 *
31 * This software component is licensed by ST under BSD 3-Clause license,
32 * the "License"; You may not use this file except in compliance with the
33 * License. You may obtain a copy of the License at:
34 * opensource.org/licenses/BSD-3-Clause
35 *
36 ******************************************************************************
37 */
38
39 /* Includes ------------------------------------------------------------------*/
40 #include "stm32f7xx_hal.h"
41
42 /** @addtogroup STM32F7xx_HAL_Driver
43 * @{
44 */
45
46 /** @defgroup DMAEx DMAEx
47 * @brief DMA Extended HAL module driver
48 * @{
49 */
50
51 #ifdef HAL_DMA_MODULE_ENABLED
52
53 /* Private types -------------------------------------------------------------*/
54 /* Private variables ---------------------------------------------------------*/
55 /* Private Constants ---------------------------------------------------------*/
56 /* Private macros ------------------------------------------------------------*/
57 /* Private functions ---------------------------------------------------------*/
58 /** @addtogroup DMAEx_Private_Functions
59 * @{
60 */
61
62 static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
63
64 /**
65 * @}
66 */
67
68 /* Exported functions ---------------------------------------------------------*/
69
70 /** @addtogroup DMAEx_Exported_Functions
71 * @{
72 */
73
74
75 /** @addtogroup DMAEx_Exported_Functions_Group1
76 *
77 @verbatim
78 ===============================================================================
79 ##### Extended features functions #####
80 ===============================================================================
81 [..] This section provides functions allowing to:
82 (+) Configure the source, destination address and data length and
83 Start MultiBuffer DMA transfer
84 (+) Configure the source, destination address and data length and
85 Start MultiBuffer DMA transfer with interrupt
86 (+) Change on the fly the memory0 or memory1 address.
87
88 @endverbatim
89 * @{
90 */
91
92
93 /**
94 * @brief Starts the multi_buffer DMA Transfer.
95 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
96 * the configuration information for the specified DMA Stream.
97 * @param SrcAddress The source memory Buffer address
98 * @param DstAddress The destination memory Buffer address
99 * @param SecondMemAddress The second memory Buffer address in case of multi buffer Transfer
100 * @param DataLength The length of data to be transferred from source to destination
101 * @retval HAL status
102 */
HAL_DMAEx_MultiBufferStart(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t SecondMemAddress,uint32_t DataLength)103 HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
104 {
105 HAL_StatusTypeDef status = HAL_OK;
106
107 /* Check the parameters */
108 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
109
110 /* Memory-to-memory transfer not supported in double buffering mode */
111 if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
112 {
113 hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
114 status = HAL_ERROR;
115 }
116 else
117 {
118 /* Process Locked */
119 __HAL_LOCK(hdma);
120
121 if(HAL_DMA_STATE_READY == hdma->State)
122 {
123 /* Change DMA peripheral state */
124 hdma->State = HAL_DMA_STATE_BUSY;
125
126 /* Enable the double buffer mode */
127 hdma->Instance->CR |= (uint32_t)DMA_SxCR_DBM;
128
129 /* Configure DMA Stream destination address */
130 hdma->Instance->M1AR = SecondMemAddress;
131
132 /* Configure the source, destination address and the data length */
133 DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);
134
135 /* Enable the peripheral */
136 __HAL_DMA_ENABLE(hdma);
137 }
138 else
139 {
140 /* Return error status */
141 status = HAL_BUSY;
142 }
143 }
144 return status;
145 }
146
147 /**
148 * @brief Starts the multi_buffer DMA Transfer with interrupt enabled.
149 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
150 * the configuration information for the specified DMA Stream.
151 * @param SrcAddress The source memory Buffer address
152 * @param DstAddress The destination memory Buffer address
153 * @param SecondMemAddress The second memory Buffer address in case of multi buffer Transfer
154 * @param DataLength The length of data to be transferred from source to destination
155 * @retval HAL status
156 */
HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t SecondMemAddress,uint32_t DataLength)157 HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
158 {
159 HAL_StatusTypeDef status = HAL_OK;
160
161 /* Check the parameters */
162 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
163
164 /* Memory-to-memory transfer not supported in double buffering mode */
165 if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
166 {
167 hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
168 return HAL_ERROR;
169 }
170
171 /* Process locked */
172 __HAL_LOCK(hdma);
173
174 if(HAL_DMA_STATE_READY == hdma->State)
175 {
176 /* Change DMA peripheral state */
177 hdma->State = HAL_DMA_STATE_BUSY;
178
179 /* Initialize the error code */
180 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
181
182 /* Enable the Double buffer mode */
183 hdma->Instance->CR |= (uint32_t)DMA_SxCR_DBM;
184
185 /* Configure DMA Stream destination address */
186 hdma->Instance->M1AR = SecondMemAddress;
187
188 /* Configure the source, destination address and the data length */
189 DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);
190
191 /* Clear all flags */
192 __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
193 __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
194 __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
195 __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
196 __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
197
198 /* Enable Common interrupts*/
199 hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
200 hdma->Instance->FCR |= DMA_IT_FE;
201
202 if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
203 {
204 hdma->Instance->CR |= DMA_IT_HT;
205 }
206
207 /* Enable the peripheral */
208 __HAL_DMA_ENABLE(hdma);
209 }
210 else
211 {
212 /* Process unlocked */
213 __HAL_UNLOCK(hdma);
214
215 /* Return error status */
216 status = HAL_BUSY;
217 }
218 return status;
219 }
220
221 /**
222 * @brief Change the memory0 or memory1 address on the fly.
223 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
224 * the configuration information for the specified DMA Stream.
225 * @param Address The new address
226 * @param memory the memory to be changed, This parameter can be one of
227 * the following values:
228 * MEMORY0 /
229 * MEMORY1
230 * @note The MEMORY0 address can be changed only when the current transfer use
231 * MEMORY1 and the MEMORY1 address can be changed only when the current
232 * transfer use MEMORY0.
233 * @retval HAL status
234 */
HAL_DMAEx_ChangeMemory(DMA_HandleTypeDef * hdma,uint32_t Address,HAL_DMA_MemoryTypeDef memory)235 HAL_StatusTypeDef HAL_DMAEx_ChangeMemory(DMA_HandleTypeDef *hdma, uint32_t Address, HAL_DMA_MemoryTypeDef memory)
236 {
237 if(memory == MEMORY0)
238 {
239 /* change the memory0 address */
240 hdma->Instance->M0AR = Address;
241 }
242 else
243 {
244 /* change the memory1 address */
245 hdma->Instance->M1AR = Address;
246 }
247
248 return HAL_OK;
249 }
250
251 /**
252 * @}
253 */
254
255 /**
256 * @}
257 */
258
259 /** @addtogroup DMAEx_Private_Functions
260 * @{
261 */
262
263 /**
264 * @brief Set the DMA Transfer parameter.
265 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
266 * the configuration information for the specified DMA Stream.
267 * @param SrcAddress The source memory Buffer address
268 * @param DstAddress The destination memory Buffer address
269 * @param DataLength The length of data to be transferred from source to destination
270 * @retval HAL status
271 */
DMA_MultiBufferSetConfig(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)272 static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
273 {
274 /* Configure DMA Stream data length */
275 hdma->Instance->NDTR = DataLength;
276
277 /* Peripheral to Memory */
278 if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
279 {
280 /* Configure DMA Stream destination address */
281 hdma->Instance->PAR = DstAddress;
282
283 /* Configure DMA Stream source address */
284 hdma->Instance->M0AR = SrcAddress;
285 }
286 /* Memory to Peripheral */
287 else
288 {
289 /* Configure DMA Stream source address */
290 hdma->Instance->PAR = SrcAddress;
291
292 /* Configure DMA Stream destination address */
293 hdma->Instance->M0AR = DstAddress;
294 }
295 }
296
297 /**
298 * @}
299 */
300
301 #endif /* HAL_DMA_MODULE_ENABLED */
302 /**
303 * @}
304 */
305
306 /**
307 * @}
308 */
309
310 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
311