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