1 /**
2 ******************************************************************************
3 * @file stm32l4xx_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 ******************************************************************************
11 * @attention
12 *
13 * Copyright (c) 2017 STMicroelectronics.
14 * All rights reserved.
15 *
16 * This software is licensed under terms that can be found in the LICENSE file
17 * in the root directory of this software component.
18 * If no LICENSE file comes with this software, it is provided AS-IS.
19 *
20 ******************************************************************************
21 @verbatim
22 ==============================================================================
23 ##### How to use this driver #####
24 ==============================================================================
25 [..]
26 The DMA Extension HAL driver can be used as follows:
27
28 (+) Configure the DMA_MUX Synchronization Block using HAL_DMAEx_ConfigMuxSync function.
29 (+) Configure the DMA_MUX Request Generator Block using HAL_DMAEx_ConfigMuxRequestGenerator function.
30 Functions HAL_DMAEx_EnableMuxRequestGenerator and HAL_DMAEx_DisableMuxRequestGenerator can then be used
31 to respectively enable/disable the request generator.
32
33 (+) To handle the DMAMUX Interrupts, the function HAL_DMAEx_MUX_IRQHandler should be called from
34 the DMAMUX IRQ handler i.e DMAMUX1_OVR_IRQHandler.
35 As only one interrupt line is available for all DMAMUX channels and request generators , HAL_DMAEx_MUX_IRQHandler should be
36 called with, as parameter, the appropriate DMA handle as many as used DMAs in the user project
37 (exception done if a given DMA is not using the DMAMUX SYNC block neither a request generator)
38
39 -@- In Memory-to-Memory transfer mode, Multi (Double) Buffer mode is not allowed.
40 -@- When Multi (Double) Buffer mode is enabled, the transfer is circular by default.
41 -@- In Multi (Double) buffer mode, it is possible to update the base address for
42 the AHB memory port on the fly (DMA_CM0ARx or DMA_CM1ARx) when the channel is enabled.
43
44
45 @endverbatim
46 ******************************************************************************
47 */
48
49 /* Includes ------------------------------------------------------------------*/
50 #include "stm32l4xx_hal.h"
51
52 #if defined(DMAMUX1)
53
54 /** @addtogroup STM32L4xx_HAL_Driver
55 * @{
56 */
57
58 /** @defgroup DMAEx DMAEx
59 * @brief DMA Extended HAL module driver
60 * @{
61 */
62
63 #ifdef HAL_DMA_MODULE_ENABLED
64
65 /* Private typedef -----------------------------------------------------------*/
66 /* Private define ------------------------------------------------------------*/
67 /* Private macro -------------------------------------------------------------*/
68 /* Private variables ---------------------------------------------------------*/
69 /* Private Constants ---------------------------------------------------------*/
70 /* Private function prototypes -----------------------------------------------*/
71 /* Private functions ---------------------------------------------------------*/
72
73
74 /** @defgroup DMAEx_Exported_Functions DMAEx Exported Functions
75 * @{
76 */
77
78 /** @defgroup DMAEx_Exported_Functions_Group1 DMAEx Extended features functions
79 * @brief Extended features functions
80 *
81 @verbatim
82 ===============================================================================
83 ##### Extended features functions #####
84 ===============================================================================
85 [..] This section provides functions allowing to:
86
87 (+) Configure the DMAMUX Synchronization Block using HAL_DMAEx_ConfigMuxSync function.
88 (+) Configure the DMAMUX Request Generator Block using HAL_DMAEx_ConfigMuxRequestGenerator function.
89 Functions HAL_DMAEx_EnableMuxRequestGenerator and HAL_DMAEx_DisableMuxRequestGenerator can then be used
90 to respectively enable/disable the request generator.
91
92 @endverbatim
93 * @{
94 */
95
96
97 /**
98 * @brief Configure the DMAMUX synchronization parameters for a given DMA channel (instance).
99 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
100 * the configuration information for the specified DMA channel.
101 * @param pSyncConfig : pointer to HAL_DMA_MuxSyncConfigTypeDef : contains the DMAMUX synchronization parameters
102 * @retval HAL status
103 */
HAL_DMAEx_ConfigMuxSync(DMA_HandleTypeDef * hdma,HAL_DMA_MuxSyncConfigTypeDef * pSyncConfig)104 HAL_StatusTypeDef HAL_DMAEx_ConfigMuxSync(DMA_HandleTypeDef *hdma, HAL_DMA_MuxSyncConfigTypeDef *pSyncConfig)
105 {
106 /* Check the parameters */
107 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
108
109 assert_param(IS_DMAMUX_SYNC_SIGNAL_ID(pSyncConfig->SyncSignalID));
110
111 assert_param(IS_DMAMUX_SYNC_POLARITY(pSyncConfig-> SyncPolarity));
112 assert_param(IS_DMAMUX_SYNC_STATE(pSyncConfig->SyncEnable));
113 assert_param(IS_DMAMUX_SYNC_EVENT(pSyncConfig->EventEnable));
114 assert_param(IS_DMAMUX_SYNC_REQUEST_NUMBER(pSyncConfig->RequestNumber));
115
116 /*Check if the DMA state is ready */
117 if(hdma->State == HAL_DMA_STATE_READY)
118 {
119 /* Process Locked */
120 __HAL_LOCK(hdma);
121
122 /* Set the new synchronization parameters (and keep the request ID filled during the Init)*/
123 MODIFY_REG( hdma->DMAmuxChannel->CCR, \
124 (~DMAMUX_CxCR_DMAREQ_ID) , \
125 ((pSyncConfig->SyncSignalID) << DMAMUX_CxCR_SYNC_ID_Pos) | ((pSyncConfig->RequestNumber - 1U) << DMAMUX_CxCR_NBREQ_Pos) | \
126 pSyncConfig->SyncPolarity | ((uint32_t)pSyncConfig->SyncEnable << DMAMUX_CxCR_SE_Pos) | \
127 ((uint32_t)pSyncConfig->EventEnable << DMAMUX_CxCR_EGE_Pos));
128
129 /* Process UnLocked */
130 __HAL_UNLOCK(hdma);
131
132 return HAL_OK;
133 }
134 else
135 {
136 /*DMA State not Ready*/
137 return HAL_ERROR;
138 }
139 }
140
141 /**
142 * @brief Configure the DMAMUX request generator block used by the given DMA channel (instance).
143 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
144 * the configuration information for the specified DMA channel.
145 * @param pRequestGeneratorConfig : pointer to HAL_DMA_MuxRequestGeneratorConfigTypeDef :
146 * contains the request generator parameters.
147 *
148 * @retval HAL status
149 */
HAL_DMAEx_ConfigMuxRequestGenerator(DMA_HandleTypeDef * hdma,HAL_DMA_MuxRequestGeneratorConfigTypeDef * pRequestGeneratorConfig)150 HAL_StatusTypeDef HAL_DMAEx_ConfigMuxRequestGenerator (DMA_HandleTypeDef *hdma, HAL_DMA_MuxRequestGeneratorConfigTypeDef *pRequestGeneratorConfig)
151 {
152 /* Check the parameters */
153 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
154
155 assert_param(IS_DMAMUX_REQUEST_GEN_SIGNAL_ID(pRequestGeneratorConfig->SignalID));
156
157 assert_param(IS_DMAMUX_REQUEST_GEN_POLARITY(pRequestGeneratorConfig->Polarity));
158 assert_param(IS_DMAMUX_REQUEST_GEN_REQUEST_NUMBER(pRequestGeneratorConfig->RequestNumber));
159
160 /* check if the DMA state is ready
161 and DMA is using a DMAMUX request generator block
162 */
163 if((hdma->State == HAL_DMA_STATE_READY) && (hdma->DMAmuxRequestGen != 0U))
164 {
165 /* Process Locked */
166 __HAL_LOCK(hdma);
167
168 /* Set the request generator new parameters */
169 hdma->DMAmuxRequestGen->RGCR = pRequestGeneratorConfig->SignalID | \
170 ((pRequestGeneratorConfig->RequestNumber - 1U) << DMAMUX_RGxCR_GNBREQ_Pos)| \
171 pRequestGeneratorConfig->Polarity;
172 /* Process UnLocked */
173 __HAL_UNLOCK(hdma);
174
175 return HAL_OK;
176 }
177 else
178 {
179 return HAL_ERROR;
180 }
181 }
182
183 /**
184 * @brief Enable the DMAMUX request generator block used by the given DMA channel (instance).
185 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
186 * the configuration information for the specified DMA channel.
187 * @retval HAL status
188 */
HAL_DMAEx_EnableMuxRequestGenerator(DMA_HandleTypeDef * hdma)189 HAL_StatusTypeDef HAL_DMAEx_EnableMuxRequestGenerator (DMA_HandleTypeDef *hdma)
190 {
191 /* Check the parameters */
192 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
193
194 /* check if the DMA state is ready
195 and DMA is using a DMAMUX request generator block
196 */
197 if((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0))
198 {
199
200 /* Enable the request generator*/
201 hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_GE;
202
203 return HAL_OK;
204 }
205 else
206 {
207 return HAL_ERROR;
208 }
209 }
210
211 /**
212 * @brief Disable the DMAMUX request generator block used by the given DMA channel (instance).
213 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
214 * the configuration information for the specified DMA channel.
215 * @retval HAL status
216 */
HAL_DMAEx_DisableMuxRequestGenerator(DMA_HandleTypeDef * hdma)217 HAL_StatusTypeDef HAL_DMAEx_DisableMuxRequestGenerator (DMA_HandleTypeDef *hdma)
218 {
219 /* Check the parameters */
220 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
221
222 /* check if the DMA state is ready
223 and DMA is using a DMAMUX request generator block
224 */
225 if((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0))
226 {
227
228 /* Disable the request generator*/
229 hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_GE;
230
231 return HAL_OK;
232 }
233 else
234 {
235 return HAL_ERROR;
236 }
237 }
238
239 /**
240 * @brief Handles DMAMUX interrupt request.
241 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
242 * the configuration information for the specified DMA channel.
243 * @retval None
244 */
HAL_DMAEx_MUX_IRQHandler(DMA_HandleTypeDef * hdma)245 void HAL_DMAEx_MUX_IRQHandler(DMA_HandleTypeDef *hdma)
246 {
247 /* Check for DMAMUX Synchronization overrun */
248 if((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
249 {
250 /* Disable the synchro overrun interrupt */
251 hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
252
253 /* Clear the DMAMUX synchro overrun flag */
254 hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
255
256 /* Update error code */
257 hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
258
259 if(hdma->XferErrorCallback != NULL)
260 {
261 /* Transfer error callback */
262 hdma->XferErrorCallback(hdma);
263 }
264 }
265
266 if(hdma->DMAmuxRequestGen != 0)
267 {
268 /* if using a DMAMUX request generator block Check for DMAMUX request generator overrun */
269 if((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
270 {
271 /* Disable the request gen overrun interrupt */
272 hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
273
274 /* Clear the DMAMUX request generator overrun flag */
275 hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
276
277 /* Update error code */
278 hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
279
280 if(hdma->XferErrorCallback != NULL)
281 {
282 /* Transfer error callback */
283 hdma->XferErrorCallback(hdma);
284 }
285 }
286 }
287 }
288
289 /**
290 * @}
291 */
292
293 /**
294 * @}
295 */
296
297 #endif /* HAL_DMA_MODULE_ENABLED */
298
299 /**
300 * @}
301 */
302
303 /**
304 * @}
305 */
306
307 #endif /* DMAMUX1 */
308