1 /**
2   ******************************************************************************
3   * @file    stm32c0xx_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   @verbatim
11   ******************************************************************************
12   * @attention
13   *
14   * Copyright (c) 2022 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
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
36        should be 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 "stm32c0xx_hal.h"
44 
45 /** @addtogroup STM32C0xx_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 DMA_MUX Synchronization Block using HAL_DMAEx_ConfigMuxSync function.
79     (+) Configure the DMA_MUX 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   * @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) << DMAMUX_CxCR_SYNC_ID_Pos) | ((pSyncConfig->RequestNumber - 1U) << \
116                                                                            DMAMUX_CxCR_NBREQ_Pos) | \
117                pSyncConfig->SyncPolarity | \
118                ((uint32_t)pSyncConfig->SyncEnable << \
119                 DMAMUX_CxCR_SE_Pos) | \
120                ((uint32_t)pSyncConfig->EventEnable << \
121                 DMAMUX_CxCR_EGE_Pos));
122 
123     /* Process UnLocked */
124     __HAL_UNLOCK(hdma);
125 
126     return HAL_OK;
127   }
128   else
129   {
130     /*DMA State not Ready*/
131     return HAL_ERROR;
132   }
133 }
134 
135 /**
136   * @brief  Configure the DMAMUX request generator block used by the given DMA channel (instance).
137   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
138   *                     the configuration information for the specified DMA channel.
139   * @param  pRequestGeneratorConfig Pointer to HAL_DMA_MuxRequestGeneratorConfigTypeDef :
140   *         contains the request generator parameters.
141   *
142   * @retval HAL status
143   */
HAL_DMAEx_ConfigMuxRequestGenerator(DMA_HandleTypeDef * hdma,HAL_DMA_MuxRequestGeneratorConfigTypeDef * pRequestGeneratorConfig)144 HAL_StatusTypeDef HAL_DMAEx_ConfigMuxRequestGenerator(DMA_HandleTypeDef *hdma,
145                                                       HAL_DMA_MuxRequestGeneratorConfigTypeDef *pRequestGeneratorConfig)
146 {
147   /* Check the parameters */
148   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
149 
150   assert_param(IS_DMAMUX_REQUEST_GEN_SIGNAL_ID(pRequestGeneratorConfig->SignalID));
151   assert_param(IS_DMAMUX_REQUEST_GEN_POLARITY(pRequestGeneratorConfig->Polarity));
152   assert_param(IS_DMAMUX_REQUEST_GEN_REQUEST_NUMBER(pRequestGeneratorConfig->RequestNumber));
153 
154   /* check if the DMA state is ready
155      and DMA is using a DMAMUX request generator block
156   */
157   if ((hdma->State == HAL_DMA_STATE_READY) && (hdma->DMAmuxRequestGen != 0U))
158   {
159     /* Process Locked */
160     __HAL_LOCK(hdma);
161 
162     /* Set the request generator new parameters*/
163     hdma->DMAmuxRequestGen->RGCR = pRequestGeneratorConfig->SignalID | \
164                                    ((pRequestGeneratorConfig->RequestNumber - 1U) << DMAMUX_RGxCR_GNBREQ_Pos) | \
165                                    pRequestGeneratorConfig->Polarity;
166     /* Process UnLocked */
167     __HAL_UNLOCK(hdma);
168 
169     return HAL_OK;
170   }
171   else
172   {
173     return HAL_ERROR;
174   }
175 }
176 
177 /**
178   * @brief  Enable the DMAMUX request generator block used by the given DMA channel (instance).
179   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
180   *                     the configuration information for the specified DMA channel.
181   * @retval HAL status
182   */
HAL_DMAEx_EnableMuxRequestGenerator(DMA_HandleTypeDef * hdma)183 HAL_StatusTypeDef HAL_DMAEx_EnableMuxRequestGenerator(DMA_HandleTypeDef *hdma)
184 {
185   /* Check the parameters */
186   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
187 
188   /* check if the DMA state is ready
189      and DMA is using a DMAMUX request generator block
190   */
191   if ((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0))
192   {
193 
194     /* Enable the request generator*/
195     hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_GE;
196 
197     return HAL_OK;
198   }
199   else
200   {
201     return HAL_ERROR;
202   }
203 }
204 
205 /**
206   * @brief  Disable the DMAMUX request generator block used by the given DMA channel (instance).
207   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
208   *                     the configuration information for the specified DMA channel.
209   * @retval HAL status
210   */
HAL_DMAEx_DisableMuxRequestGenerator(DMA_HandleTypeDef * hdma)211 HAL_StatusTypeDef HAL_DMAEx_DisableMuxRequestGenerator(DMA_HandleTypeDef *hdma)
212 {
213   /* Check the parameters */
214   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
215 
216   /* check if the DMA state is ready
217      and DMA is using a DMAMUX request generator block
218   */
219   if ((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0))
220   {
221 
222     /* Disable the request generator*/
223     hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_GE;
224 
225     return HAL_OK;
226   }
227   else
228   {
229     return HAL_ERROR;
230   }
231 }
232 
233 /**
234   * @brief  Handles DMAMUX interrupt request.
235   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
236   *               the configuration information for the specified DMA channel.
237   * @retval None
238   */
HAL_DMAEx_MUX_IRQHandler(DMA_HandleTypeDef * hdma)239 void HAL_DMAEx_MUX_IRQHandler(DMA_HandleTypeDef *hdma)
240 {
241   /* Check for DMAMUX Synchronization overrun */
242   if ((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
243   {
244     /* Disable the synchro overrun interrupt */
245     hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
246 
247     /* Clear the DMAMUX synchro overrun flag */
248     hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
249 
250     /* Update error code */
251     hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
252 
253     if (hdma->XferErrorCallback != NULL)
254     {
255       /* Transfer error callback */
256       hdma->XferErrorCallback(hdma);
257     }
258   }
259 
260   if (hdma->DMAmuxRequestGen != 0)
261   {
262     /* if using a DMAMUX request generator block Check for DMAMUX request generator overrun */
263     if ((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
264     {
265       /* Disable the request gen overrun interrupt */
266       hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
267 
268       /* Clear the DMAMUX request generator overrun flag */
269       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
270 
271       /* Update error code */
272       hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
273 
274       if (hdma->XferErrorCallback != NULL)
275       {
276         /* Transfer error callback */
277         hdma->XferErrorCallback(hdma);
278       }
279     }
280   }
281 }
282 
283 /**
284   * @}
285   */
286 
287 /**
288   * @}
289   */
290 
291 #endif /* HAL_DMA_MODULE_ENABLED */
292 /**
293   * @}
294   */
295 
296 /**
297   * @}
298   */
299