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