1 /**
2   ******************************************************************************
3   * @file    stm32g4xx_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) 2019 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   @endverbatim
40   */
41 
42 /* Includes ------------------------------------------------------------------*/
43 #include "stm32g4xx_hal.h"
44 
45 /** @addtogroup STM32G4xx_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 /* Private 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 
83 @endverbatim
84   * @{
85   */
86 
87 
88 /**
89   * @brief  Configure the DMAMUX synchronization parameters for a given DMA channel (instance).
90   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
91   *                     the configuration information for the specified DMA channel.
92   * @param  pSyncConfig : pointer to HAL_DMA_MuxSyncConfigTypeDef : contains the DMAMUX synchronization parameters
93   * @retval HAL status
94   */
HAL_DMAEx_ConfigMuxSync(DMA_HandleTypeDef * hdma,HAL_DMA_MuxSyncConfigTypeDef * pSyncConfig)95 HAL_StatusTypeDef HAL_DMAEx_ConfigMuxSync(DMA_HandleTypeDef *hdma, HAL_DMA_MuxSyncConfigTypeDef *pSyncConfig)
96 {
97   /* Check the parameters */
98   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
99 
100   assert_param(IS_DMAMUX_SYNC_SIGNAL_ID(pSyncConfig->SyncSignalID));
101 
102   assert_param(IS_DMAMUX_SYNC_POLARITY(pSyncConfig-> SyncPolarity));
103   assert_param(IS_DMAMUX_SYNC_STATE(pSyncConfig->SyncEnable));
104   assert_param(IS_DMAMUX_SYNC_EVENT(pSyncConfig->EventEnable));
105   assert_param(IS_DMAMUX_SYNC_REQUEST_NUMBER(pSyncConfig->RequestNumber));
106 
107   /*Check if the DMA state is ready */
108   if (hdma->State == HAL_DMA_STATE_READY)
109   {
110     /* Process Locked */
111     __HAL_LOCK(hdma);
112 
113     /* Set the new synchronization parameters (and keep the request ID filled during the Init)*/
114     MODIFY_REG(hdma->DMAmuxChannel->CCR, \
115                (~DMAMUX_CxCR_DMAREQ_ID), \
116                ((pSyncConfig->SyncSignalID) << DMAMUX_CxCR_SYNC_ID_Pos) | ((pSyncConfig->RequestNumber - 1U) << DMAMUX_CxCR_NBREQ_Pos) | \
117                pSyncConfig->SyncPolarity | ((uint32_t)pSyncConfig->SyncEnable << DMAMUX_CxCR_SE_Pos) | \
118                ((uint32_t)pSyncConfig->EventEnable << DMAMUX_CxCR_EGE_Pos));
119 
120     /* Process UnLocked */
121     __HAL_UNLOCK(hdma);
122 
123     return HAL_OK;
124   }
125   else
126   {
127     /*DMA State not Ready*/
128     return HAL_ERROR;
129   }
130 }
131 
132 /**
133   * @brief  Configure the DMAMUX request generator block used by the given DMA channel (instance).
134   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
135   *                     the configuration information for the specified DMA channel.
136   * @param  pRequestGeneratorConfig : pointer to HAL_DMA_MuxRequestGeneratorConfigTypeDef :
137   *         contains the request generator parameters.
138   *
139   * @retval HAL status
140   */
HAL_DMAEx_ConfigMuxRequestGenerator(DMA_HandleTypeDef * hdma,HAL_DMA_MuxRequestGeneratorConfigTypeDef * pRequestGeneratorConfig)141 HAL_StatusTypeDef HAL_DMAEx_ConfigMuxRequestGenerator(DMA_HandleTypeDef *hdma,
142                                                       HAL_DMA_MuxRequestGeneratorConfigTypeDef *pRequestGeneratorConfig)
143 {
144   /* Check the parameters */
145   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
146 
147   assert_param(IS_DMAMUX_REQUEST_GEN_SIGNAL_ID(pRequestGeneratorConfig->SignalID));
148 
149   assert_param(IS_DMAMUX_REQUEST_GEN_POLARITY(pRequestGeneratorConfig->Polarity));
150   assert_param(IS_DMAMUX_REQUEST_GEN_REQUEST_NUMBER(pRequestGeneratorConfig->RequestNumber));
151 
152   /* check if the DMA state is ready
153      and DMA is using a DMAMUX request generator block
154   */
155   if ((hdma->State == HAL_DMA_STATE_READY) && (hdma->DMAmuxRequestGen != 0U))
156   {
157     /* Process Locked */
158     __HAL_LOCK(hdma);
159 
160     /* Set the request generator new parameters */
161     hdma->DMAmuxRequestGen->RGCR = pRequestGeneratorConfig->SignalID | \
162                                    ((pRequestGeneratorConfig->RequestNumber - 1U) << (POSITION_VAL(DMAMUX_RGxCR_GNBREQ) & 0x1FU)) | \
163                                    pRequestGeneratorConfig->Polarity;
164     /* Process UnLocked */
165     __HAL_UNLOCK(hdma);
166 
167     return HAL_OK;
168   }
169   else
170   {
171     return HAL_ERROR;
172   }
173 }
174 
175 /**
176   * @brief  Enable the DMAMUX request generator block used by the given DMA channel (instance).
177   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
178   *                     the configuration information for the specified DMA channel.
179   * @retval HAL status
180   */
HAL_DMAEx_EnableMuxRequestGenerator(DMA_HandleTypeDef * hdma)181 HAL_StatusTypeDef HAL_DMAEx_EnableMuxRequestGenerator(DMA_HandleTypeDef *hdma)
182 {
183   /* Check the parameters */
184   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
185 
186   /* check if the DMA state is ready
187      and DMA is using a DMAMUX request generator block
188   */
189   if ((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0))
190   {
191 
192     /* Enable the request generator*/
193     hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_GE;
194 
195     return HAL_OK;
196   }
197   else
198   {
199     return HAL_ERROR;
200   }
201 }
202 
203 /**
204   * @brief  Disable the DMAMUX request generator block used by the given DMA channel (instance).
205   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
206   *                     the configuration information for the specified DMA channel.
207   * @retval HAL status
208   */
HAL_DMAEx_DisableMuxRequestGenerator(DMA_HandleTypeDef * hdma)209 HAL_StatusTypeDef HAL_DMAEx_DisableMuxRequestGenerator(DMA_HandleTypeDef *hdma)
210 {
211   /* Check the parameters */
212   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
213 
214   /* check if the DMA state is ready
215      and DMA is using a DMAMUX request generator block
216   */
217   if ((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0))
218   {
219 
220     /* Disable the request generator*/
221     hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_GE;
222 
223     return HAL_OK;
224   }
225   else
226   {
227     return HAL_ERROR;
228   }
229 }
230 
231 /**
232   * @brief  Handles DMAMUX interrupt request.
233   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
234   *               the configuration information for the specified DMA channel.
235   * @retval None
236   */
HAL_DMAEx_MUX_IRQHandler(DMA_HandleTypeDef * hdma)237 void HAL_DMAEx_MUX_IRQHandler(DMA_HandleTypeDef *hdma)
238 {
239   /* Check for DMAMUX Synchronization overrun */
240   if ((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
241   {
242     /* Disable the synchro overrun interrupt */
243     hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
244 
245     /* Clear the DMAMUX synchro overrun flag */
246     hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
247 
248     /* Update error code */
249     hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
250 
251     if (hdma->XferErrorCallback != NULL)
252     {
253       /* Transfer error callback */
254       hdma->XferErrorCallback(hdma);
255     }
256   }
257 
258   if (hdma->DMAmuxRequestGen != 0)
259   {
260     /* if using a DMAMUX request generator block Check for DMAMUX request generator overrun */
261     if ((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
262     {
263       /* Disable the request gen overrun interrupt */
264       hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
265 
266       /* Clear the DMAMUX request generator overrun flag */
267       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
268 
269       /* Update error code */
270       hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
271 
272       if (hdma->XferErrorCallback != NULL)
273       {
274         /* Transfer error callback */
275         hdma->XferErrorCallback(hdma);
276       }
277     }
278   }
279 }
280 
281 /**
282   * @}
283   */
284 
285 /**
286   * @}
287   */
288 
289 #endif /* HAL_DMA_MODULE_ENABLED */
290 
291 /**
292   * @}
293   */
294 
295 /**
296   * @}
297   */
298 
299