1 /**
2   ******************************************************************************
3   * @file    stm32wbxx_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 
43 /* Includes ------------------------------------------------------------------*/
44 #include "stm32wbxx_hal.h"
45 
46 /** @addtogroup STM32WBxx_HAL_Driver
47   * @{
48   */
49 
50 /** @defgroup DMAEx DMAEx
51   * @brief DMA Extended HAL module driver
52   * @{
53   */
54 
55 #ifdef HAL_DMA_MODULE_ENABLED
56 
57 /* Private typedef -----------------------------------------------------------*/
58 /* Private define ------------------------------------------------------------*/
59 /* Private macro -------------------------------------------------------------*/
60 /* Private variables ---------------------------------------------------------*/
61 /* Private Constants ---------------------------------------------------------*/
62 /* Private function prototypes -----------------------------------------------*/
63 /* Private functions ---------------------------------------------------------*/
64 
65 
66 /** @defgroup DMAEx_Exported_Functions DMAEx Exported Functions
67   * @{
68   */
69 
70 /** @defgroup DMAEx_Exported_Functions_Group1 DMAEx Extended features functions
71   *  @brief   Extended features functions
72   *
73 @verbatim
74  ===============================================================================
75                 #####  Extended features functions  #####
76  ===============================================================================
77     [..]  This section provides functions allowing to:
78 
79     (+) Configure the DMAMUX Synchronization Block using HAL_DMAEx_ConfigMuxSync function.
80     (+) Configure the DMAMUX Request Generator Block using HAL_DMAEx_ConfigMuxRequestGenerator function.
81        Functions HAL_DMAEx_EnableMuxRequestGenerator and HAL_DMAEx_DisableMuxRequestGenerator can then be used
82        to respectively enable/disable the request generator.
83 
84 @endverbatim
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   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_SYNC_ID | DMAMUX_CxCR_NBREQ | DMAMUX_CxCR_SPOL | DMAMUX_CxCR_SE | DMAMUX_CxCR_EGE), \
115                (pSyncConfig->SyncSignalID                                       | \
116                 ((pSyncConfig->RequestNumber - 1U) << DMAMUX_CxCR_NBREQ_Pos)    | \
117                 pSyncConfig->SyncPolarity                                       | \
118                 ((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     /*DMA State not Ready*/
129     return HAL_ERROR;
130   }
131 }
132 
133 /**
134   * @brief  Configure the DMAMUX request generator block used by the given DMA channel (instance).
135   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
136   *                     the configuration information for the specified DMA channel.
137   * @param  pRequestGeneratorConfig Pointer to HAL_DMA_MuxRequestGeneratorConfigTypeDef :
138   *         contains the request generator parameters.
139   *
140   * @retval HAL status
141   */
HAL_DMAEx_ConfigMuxRequestGenerator(DMA_HandleTypeDef * hdma,HAL_DMA_MuxRequestGeneratorConfigTypeDef * pRequestGeneratorConfig)142 HAL_StatusTypeDef HAL_DMAEx_ConfigMuxRequestGenerator(DMA_HandleTypeDef *hdma,
143                                                       HAL_DMA_MuxRequestGeneratorConfigTypeDef *pRequestGeneratorConfig)
144 {
145   /* Check the parameters */
146   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
147 
148   assert_param(IS_DMAMUX_REQUEST_GEN_SIGNAL_ID(pRequestGeneratorConfig->SignalID));
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     WRITE_REG(hdma->DMAmuxRequestGen->RGCR, (pRequestGeneratorConfig->SignalID       | \
162                                              pRequestGeneratorConfig->Polarity       | \
163                                              ((pRequestGeneratorConfig->RequestNumber - 1U) << DMAMUX_RGxCR_GNBREQ_Pos)));
164 
165     /* Process UnLocked */
166     __HAL_UNLOCK(hdma);
167 
168     return HAL_OK;
169   }
170   else
171   {
172     return HAL_ERROR;
173   }
174 }
175 
176 /**
177   * @brief  Enable the DMAMUX request generator block used by the given DMA channel (instance).
178   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
179   *                     the configuration information for the specified DMA channel.
180   * @retval HAL status
181   */
HAL_DMAEx_EnableMuxRequestGenerator(DMA_HandleTypeDef * hdma)182 HAL_StatusTypeDef HAL_DMAEx_EnableMuxRequestGenerator(DMA_HandleTypeDef *hdma)
183 {
184   /* Check the parameters */
185   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
186 
187   /* check if the DMA state is ready
188      and DMA is using a DMAMUX request generator block
189   */
190   if ((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0U))
191   {
192     /* Enable the request generator*/
193     SET_BIT(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     /* Disable the request generator*/
220     CLEAR_BIT(hdma->DMAmuxRequestGen->RGCR, DMAMUX_RGxCR_GE);
221 
222     return HAL_OK;
223   }
224   else
225   {
226     return HAL_ERROR;
227   }
228 }
229 
230 /**
231   * @brief  Handles DMAMUX interrupt request.
232   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
233   *               the configuration information for the specified DMA channel.
234   * @retval None
235   */
HAL_DMAEx_MUX_IRQHandler(DMA_HandleTypeDef * hdma)236 void HAL_DMAEx_MUX_IRQHandler(DMA_HandleTypeDef *hdma)
237 {
238   /* Check for DMAMUX Synchronization overrun */
239   if ((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
240   {
241     /* Disable the synchro overrun interrupt */
242     CLEAR_BIT(hdma->DMAmuxChannel->CCR, DMAMUX_CxCR_SOIE);
243 
244     /* Clear the DMAMUX synchro overrun flag */
245     WRITE_REG(hdma->DMAmuxChannelStatus->CFR, hdma->DMAmuxChannelStatusMask);
246 
247     /* Update error code */
248     hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
249 
250     if (hdma->XferErrorCallback != NULL)
251     {
252       /* Transfer error callback */
253       hdma->XferErrorCallback(hdma);
254     }
255   }
256 
257   if (hdma->DMAmuxRequestGen != 0U)
258   {
259     /* if using a DMAMUX request generator block Check for DMAMUX request generator overrun */
260     if ((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
261     {
262       /* Disable the request gen overrun interrupt */
263       CLEAR_BIT(hdma->DMAmuxRequestGen->RGCR, DMAMUX_RGxCR_OIE);
264 
265       /* Clear the DMAMUX request generator overrun flag */
266       WRITE_REG(hdma->DMAmuxRequestGenStatus->RGCFR, hdma->DMAmuxRequestGenStatusMask);
267 
268       /* Update error code */
269       hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
270 
271       if (hdma->XferErrorCallback != NULL)
272       {
273         /* Transfer error callback */
274         hdma->XferErrorCallback(hdma);
275       }
276     }
277   }
278 }
279 
280 /**
281   * @}
282   */
283 
284 /**
285   * @}
286   */
287 
288 #endif /* HAL_DMA_MODULE_ENABLED */
289 /**
290   * @}
291   */
292 
293 /**
294   * @}
295   */
296