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