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