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