STM32L486xx HAL User Manual
stm32l4xx_ll_dma.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_ll_dma.c
00004   * @author  MCD Application Team
00005   * @brief   DMA LL module driver.
00006   ******************************************************************************
00007   * @attention
00008   *
00009   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
00010   *
00011   * Redistribution and use in source and binary forms, with or without modification,
00012   * are permitted provided that the following conditions are met:
00013   *   1. Redistributions of source code must retain the above copyright notice,
00014   *      this list of conditions and the following disclaimer.
00015   *   2. Redistributions in binary form must reproduce the above copyright notice,
00016   *      this list of conditions and the following disclaimer in the documentation
00017   *      and/or other materials provided with the distribution.
00018   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00019   *      may be used to endorse or promote products derived from this software
00020   *      without specific prior written permission.
00021   *
00022   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00023   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00025   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00026   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00028   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00030   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00031   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032   *
00033   ******************************************************************************
00034   */
00035 #if defined(USE_FULL_LL_DRIVER)
00036 
00037 /* Includes ------------------------------------------------------------------*/
00038 #include "stm32l4xx_ll_dma.h"
00039 #include "stm32l4xx_ll_bus.h"
00040 #ifdef  USE_FULL_ASSERT
00041 #include "stm32_assert.h"
00042 #else
00043 #define assert_param(expr) ((void)0U)
00044 #endif
00045 
00046 /** @addtogroup STM32L4xx_LL_Driver
00047   * @{
00048   */
00049 
00050 #if defined (DMA1) || defined (DMA2)
00051 
00052 /** @defgroup DMA_LL DMA
00053   * @{
00054   */
00055 
00056 /* Private types -------------------------------------------------------------*/
00057 /* Private variables ---------------------------------------------------------*/
00058 /* Private constants ---------------------------------------------------------*/
00059 /* Private macros ------------------------------------------------------------*/
00060 /** @addtogroup DMA_LL_Private_Macros
00061   * @{
00062   */
00063 #define IS_LL_DMA_DIRECTION(__VALUE__)          (((__VALUE__) == LL_DMA_DIRECTION_PERIPH_TO_MEMORY) || \
00064                                                  ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_PERIPH) || \
00065                                                  ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_MEMORY))
00066 
00067 #define IS_LL_DMA_MODE(__VALUE__)               (((__VALUE__) == LL_DMA_MODE_NORMAL) || \
00068                                                  ((__VALUE__) == LL_DMA_MODE_CIRCULAR))
00069 
00070 #define IS_LL_DMA_PERIPHINCMODE(__VALUE__)      (((__VALUE__) == LL_DMA_PERIPH_INCREMENT) || \
00071                                                  ((__VALUE__) == LL_DMA_PERIPH_NOINCREMENT))
00072 
00073 #define IS_LL_DMA_MEMORYINCMODE(__VALUE__)      (((__VALUE__) == LL_DMA_MEMORY_INCREMENT) || \
00074                                                  ((__VALUE__) == LL_DMA_MEMORY_NOINCREMENT))
00075 
00076 #define IS_LL_DMA_PERIPHDATASIZE(__VALUE__)     (((__VALUE__) == LL_DMA_PDATAALIGN_BYTE)      || \
00077                                                  ((__VALUE__) == LL_DMA_PDATAALIGN_HALFWORD)  || \
00078                                                  ((__VALUE__) == LL_DMA_PDATAALIGN_WORD))
00079 
00080 #define IS_LL_DMA_MEMORYDATASIZE(__VALUE__)     (((__VALUE__) == LL_DMA_MDATAALIGN_BYTE)      || \
00081                                                  ((__VALUE__) == LL_DMA_MDATAALIGN_HALFWORD)  || \
00082                                                  ((__VALUE__) == LL_DMA_MDATAALIGN_WORD))
00083 
00084 #define IS_LL_DMA_NBDATA(__VALUE__)             ((__VALUE__)  <= 0x0000FFFFU)
00085 
00086 #if defined(DMAMUX1)
00087 #define IS_LL_DMA_PERIPHREQUEST(__VALUE__)      ((__VALUE__) <= 93U)
00088 #else
00089 #define IS_LL_DMA_PERIPHREQUEST(__VALUE__)      (((__VALUE__) == LL_DMA_REQUEST_0)  || \
00090                                                  ((__VALUE__) == LL_DMA_REQUEST_1)  || \
00091                                                  ((__VALUE__) == LL_DMA_REQUEST_2)  || \
00092                                                  ((__VALUE__) == LL_DMA_REQUEST_3)  || \
00093                                                  ((__VALUE__) == LL_DMA_REQUEST_4)  || \
00094                                                  ((__VALUE__) == LL_DMA_REQUEST_5)  || \
00095                                                  ((__VALUE__) == LL_DMA_REQUEST_6)  || \
00096                                                  ((__VALUE__) == LL_DMA_REQUEST_7))
00097 #endif /* DMAMUX1 */
00098 
00099 #define IS_LL_DMA_PRIORITY(__VALUE__)           (((__VALUE__) == LL_DMA_PRIORITY_LOW)    || \
00100                                                  ((__VALUE__) == LL_DMA_PRIORITY_MEDIUM) || \
00101                                                  ((__VALUE__) == LL_DMA_PRIORITY_HIGH)   || \
00102                                                  ((__VALUE__) == LL_DMA_PRIORITY_VERYHIGH))
00103 
00104 #if defined (DMA2)
00105 #if defined (DMA2_Channel6) && defined (DMA2_Channel7)
00106 #define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL)  ((((INSTANCE) == DMA1) && \
00107                                                          (((CHANNEL) == LL_DMA_CHANNEL_1) || \
00108                                                           ((CHANNEL) == LL_DMA_CHANNEL_2) || \
00109                                                           ((CHANNEL) == LL_DMA_CHANNEL_3) || \
00110                                                           ((CHANNEL) == LL_DMA_CHANNEL_4) || \
00111                                                           ((CHANNEL) == LL_DMA_CHANNEL_5) || \
00112                                                           ((CHANNEL) == LL_DMA_CHANNEL_6) || \
00113                                                           ((CHANNEL) == LL_DMA_CHANNEL_7))) || \
00114                                                          (((INSTANCE) == DMA2) && \
00115                                                          (((CHANNEL) == LL_DMA_CHANNEL_1) || \
00116                                                           ((CHANNEL) == LL_DMA_CHANNEL_2) || \
00117                                                           ((CHANNEL) == LL_DMA_CHANNEL_3) || \
00118                                                           ((CHANNEL) == LL_DMA_CHANNEL_4) || \
00119                                                           ((CHANNEL) == LL_DMA_CHANNEL_5) || \
00120                                                           ((CHANNEL) == LL_DMA_CHANNEL_6) || \
00121                                                           ((CHANNEL) == LL_DMA_CHANNEL_7))))
00122 #else
00123 #define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL)  ((((INSTANCE) == DMA1) && \
00124                                                          (((CHANNEL) == LL_DMA_CHANNEL_1) || \
00125                                                           ((CHANNEL) == LL_DMA_CHANNEL_2) || \
00126                                                           ((CHANNEL) == LL_DMA_CHANNEL_3) || \
00127                                                           ((CHANNEL) == LL_DMA_CHANNEL_4) || \
00128                                                           ((CHANNEL) == LL_DMA_CHANNEL_5) || \
00129                                                           ((CHANNEL) == LL_DMA_CHANNEL_6) || \
00130                                                           ((CHANNEL) == LL_DMA_CHANNEL_7))) || \
00131                                                          (((INSTANCE) == DMA2) && \
00132                                                          (((CHANNEL) == LL_DMA_CHANNEL_1) || \
00133                                                           ((CHANNEL) == LL_DMA_CHANNEL_2) || \
00134                                                           ((CHANNEL) == LL_DMA_CHANNEL_3) || \
00135                                                           ((CHANNEL) == LL_DMA_CHANNEL_4) || \
00136                                                           ((CHANNEL) == LL_DMA_CHANNEL_5))))
00137 #endif
00138 #else
00139 #define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL)  ((((INSTANCE) == DMA1) && \
00140                                                             (((CHANNEL) == LL_DMA_CHANNEL_1)|| \
00141                                                             ((CHANNEL) == LL_DMA_CHANNEL_2) || \
00142                                                             ((CHANNEL) == LL_DMA_CHANNEL_3) || \
00143                                                             ((CHANNEL) == LL_DMA_CHANNEL_4) || \
00144                                                             ((CHANNEL) == LL_DMA_CHANNEL_5) || \
00145                                                             ((CHANNEL) == LL_DMA_CHANNEL_6) || \
00146                                                             ((CHANNEL) == LL_DMA_CHANNEL_7))))
00147 #endif
00148 /**
00149   * @}
00150   */
00151 
00152 /* Private function prototypes -----------------------------------------------*/
00153 
00154 /* Exported functions --------------------------------------------------------*/
00155 /** @addtogroup DMA_LL_Exported_Functions
00156   * @{
00157   */
00158 
00159 /** @addtogroup DMA_LL_EF_Init
00160   * @{
00161   */
00162 
00163 /**
00164   * @brief  De-initialize the DMA registers to their default reset values.
00165   * @param  DMAx DMAx Instance
00166   * @param  Channel This parameter can be one of the following values:
00167   *         @arg @ref LL_DMA_CHANNEL_1
00168   *         @arg @ref LL_DMA_CHANNEL_2
00169   *         @arg @ref LL_DMA_CHANNEL_3
00170   *         @arg @ref LL_DMA_CHANNEL_4
00171   *         @arg @ref LL_DMA_CHANNEL_5
00172   *         @arg @ref LL_DMA_CHANNEL_6
00173   *         @arg @ref LL_DMA_CHANNEL_7
00174   *         @arg @ref LL_DMA_CHANNEL_ALL
00175   * @retval An ErrorStatus enumeration value:
00176   *          - SUCCESS: DMA registers are de-initialized
00177   *          - ERROR: DMA registers are not de-initialized
00178   */
00179 uint32_t LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel)
00180 {
00181   DMA_Channel_TypeDef *tmp = (DMA_Channel_TypeDef *)DMA1_Channel1;
00182   ErrorStatus status = SUCCESS;
00183 
00184   /* Check the DMA Instance DMAx and Channel parameters*/
00185   assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel) || (Channel == LL_DMA_CHANNEL_ALL));
00186 
00187   if (Channel == LL_DMA_CHANNEL_ALL)
00188   {
00189     if (DMAx == DMA1)
00190     {
00191       /* Force reset of DMA clock */
00192       LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA1);
00193 
00194       /* Release reset of DMA clock */
00195       LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA1);
00196     }
00197 #if defined(DMA2)
00198     else if (DMAx == DMA2)
00199     {
00200       /* Force reset of DMA clock */
00201       LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA2);
00202 
00203       /* Release reset of DMA clock */
00204       LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA2);
00205     }
00206 #endif
00207     else
00208     {
00209       status = ERROR;
00210     }
00211   }
00212   else
00213   {
00214     tmp = (DMA_Channel_TypeDef *)(__LL_DMA_GET_CHANNEL_INSTANCE(DMAx, Channel));
00215 
00216     /* Disable the selected DMAx_Channely */
00217     CLEAR_BIT(tmp->CCR, DMA_CCR_EN);
00218 
00219     /* Reset DMAx_Channely control register */
00220     LL_DMA_WriteReg(tmp, CCR, 0U);
00221 
00222     /* Reset DMAx_Channely remaining bytes register */
00223     LL_DMA_WriteReg(tmp, CNDTR, 0U);
00224 
00225     /* Reset DMAx_Channely peripheral address register */
00226     LL_DMA_WriteReg(tmp, CPAR, 0U);
00227 
00228     /* Reset DMAx_Channely memory address register */
00229     LL_DMA_WriteReg(tmp, CMAR, 0U);
00230 
00231 #if defined(DMAMUX1)
00232     /* Reset Request register field for DMAx Channel */
00233     LL_DMA_SetPeriphRequest(DMAx, Channel, LL_DMAMUX_REQUEST_MEM2MEM);
00234 #else
00235     /* Reset Request register field for DMAx Channel */
00236     LL_DMA_SetPeriphRequest(DMAx, Channel, LL_DMA_REQUEST_0);
00237 #endif /* DMAMUX1 */
00238 
00239     if (Channel == LL_DMA_CHANNEL_1)
00240     {
00241       /* Reset interrupt pending bits for DMAx Channel1 */
00242       LL_DMA_ClearFlag_GI1(DMAx);
00243     }
00244     else if (Channel == LL_DMA_CHANNEL_2)
00245     {
00246       /* Reset interrupt pending bits for DMAx Channel2 */
00247       LL_DMA_ClearFlag_GI2(DMAx);
00248     }
00249     else if (Channel == LL_DMA_CHANNEL_3)
00250     {
00251       /* Reset interrupt pending bits for DMAx Channel3 */
00252       LL_DMA_ClearFlag_GI3(DMAx);
00253     }
00254     else if (Channel == LL_DMA_CHANNEL_4)
00255     {
00256       /* Reset interrupt pending bits for DMAx Channel4 */
00257       LL_DMA_ClearFlag_GI4(DMAx);
00258     }
00259     else if (Channel == LL_DMA_CHANNEL_5)
00260     {
00261       /* Reset interrupt pending bits for DMAx Channel5 */
00262       LL_DMA_ClearFlag_GI5(DMAx);
00263     }
00264 
00265     else if (Channel == LL_DMA_CHANNEL_6)
00266     {
00267       /* Reset interrupt pending bits for DMAx Channel6 */
00268       LL_DMA_ClearFlag_GI6(DMAx);
00269     }
00270     else if (Channel == LL_DMA_CHANNEL_7)
00271     {
00272       /* Reset interrupt pending bits for DMAx Channel7 */
00273       LL_DMA_ClearFlag_GI7(DMAx);
00274     }
00275     else
00276     {
00277       status = ERROR;
00278     }
00279   }
00280 
00281   return status;
00282 }
00283 
00284 /**
00285   * @brief  Initialize the DMA registers according to the specified parameters in DMA_InitStruct.
00286   * @note   To convert DMAx_Channely Instance to DMAx Instance and Channely, use helper macros :
00287   *         @arg @ref __LL_DMA_GET_INSTANCE
00288   *         @arg @ref __LL_DMA_GET_CHANNEL
00289   * @param  DMAx DMAx Instance
00290   * @param  Channel This parameter can be one of the following values:
00291   *         @arg @ref LL_DMA_CHANNEL_1
00292   *         @arg @ref LL_DMA_CHANNEL_2
00293   *         @arg @ref LL_DMA_CHANNEL_3
00294   *         @arg @ref LL_DMA_CHANNEL_4
00295   *         @arg @ref LL_DMA_CHANNEL_5
00296   *         @arg @ref LL_DMA_CHANNEL_6
00297   *         @arg @ref LL_DMA_CHANNEL_7
00298   * @param  DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure.
00299   * @retval An ErrorStatus enumeration value:
00300   *          - SUCCESS: DMA registers are initialized
00301   *          - ERROR: Not applicable
00302   */
00303 uint32_t LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitTypeDef *DMA_InitStruct)
00304 {
00305   /* Check the DMA Instance DMAx and Channel parameters*/
00306   assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel));
00307 
00308   /* Check the DMA parameters from DMA_InitStruct */
00309   assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction));
00310   assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode));
00311   assert_param(IS_LL_DMA_PERIPHINCMODE(DMA_InitStruct->PeriphOrM2MSrcIncMode));
00312   assert_param(IS_LL_DMA_MEMORYINCMODE(DMA_InitStruct->MemoryOrM2MDstIncMode));
00313   assert_param(IS_LL_DMA_PERIPHDATASIZE(DMA_InitStruct->PeriphOrM2MSrcDataSize));
00314   assert_param(IS_LL_DMA_MEMORYDATASIZE(DMA_InitStruct->MemoryOrM2MDstDataSize));
00315   assert_param(IS_LL_DMA_NBDATA(DMA_InitStruct->NbData));
00316   assert_param(IS_LL_DMA_PERIPHREQUEST(DMA_InitStruct->PeriphRequest));
00317   assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority));
00318 
00319   /*---------------------------- DMAx CCR Configuration ------------------------
00320    * Configure DMAx_Channely: data transfer direction, data transfer mode,
00321    *                          peripheral and memory increment mode,
00322    *                          data size alignment and  priority level with parameters :
00323    * - Direction:      DMA_CCR_DIR and DMA_CCR_MEM2MEM bits
00324    * - Mode:           DMA_CCR_CIRC bit
00325    * - PeriphOrM2MSrcIncMode:  DMA_CCR_PINC bit
00326    * - MemoryOrM2MDstIncMode:  DMA_CCR_MINC bit
00327    * - PeriphOrM2MSrcDataSize: DMA_CCR_PSIZE[1:0] bits
00328    * - MemoryOrM2MDstDataSize: DMA_CCR_MSIZE[1:0] bits
00329    * - Priority:               DMA_CCR_PL[1:0] bits
00330    */
00331   LL_DMA_ConfigTransfer(DMAx, Channel, DMA_InitStruct->Direction              | \
00332                         DMA_InitStruct->Mode                   | \
00333                         DMA_InitStruct->PeriphOrM2MSrcIncMode  | \
00334                         DMA_InitStruct->MemoryOrM2MDstIncMode  | \
00335                         DMA_InitStruct->PeriphOrM2MSrcDataSize | \
00336                         DMA_InitStruct->MemoryOrM2MDstDataSize | \
00337                         DMA_InitStruct->Priority);
00338 
00339   /*-------------------------- DMAx CMAR Configuration -------------------------
00340    * Configure the memory or destination base address with parameter :
00341    * - MemoryOrM2MDstAddress: DMA_CMAR_MA[31:0] bits
00342    */
00343   LL_DMA_SetMemoryAddress(DMAx, Channel, DMA_InitStruct->MemoryOrM2MDstAddress);
00344 
00345   /*-------------------------- DMAx CPAR Configuration -------------------------
00346    * Configure the peripheral or source base address with parameter :
00347    * - PeriphOrM2MSrcAddress: DMA_CPAR_PA[31:0] bits
00348    */
00349   LL_DMA_SetPeriphAddress(DMAx, Channel, DMA_InitStruct->PeriphOrM2MSrcAddress);
00350 
00351   /*--------------------------- DMAx CNDTR Configuration -----------------------
00352    * Configure the peripheral base address with parameter :
00353    * - NbData: DMA_CNDTR_NDT[15:0] bits
00354    */
00355   LL_DMA_SetDataLength(DMAx, Channel, DMA_InitStruct->NbData);
00356 
00357 #if defined(DMAMUX1)
00358   /*--------------------------- DMAMUXx CCR Configuration ----------------------
00359    * Configure the DMA request for DMA Channels on DMAMUX Channel x with parameter :
00360    * - PeriphRequest: DMA_CxCR[7:0] bits
00361    */
00362   LL_DMA_SetPeriphRequest(DMAx, Channel, DMA_InitStruct->PeriphRequest);
00363 #else
00364   /*--------------------------- DMAx CSELR Configuration -----------------------
00365    * Configure the DMA request for DMA instance on Channel x with parameter :
00366    * - PeriphRequest: DMA_CSELR[31:0] bits
00367    */
00368   LL_DMA_SetPeriphRequest(DMAx, Channel, DMA_InitStruct->PeriphRequest);
00369 #endif /* DMAMUX1 */
00370 
00371   return SUCCESS;
00372 }
00373 
00374 /**
00375   * @brief  Set each @ref LL_DMA_InitTypeDef field to default value.
00376   * @param  DMA_InitStruct Pointer to a @ref LL_DMA_InitTypeDef structure.
00377   * @retval None
00378   */
00379 void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct)
00380 {
00381   /* Set DMA_InitStruct fields to default values */
00382   DMA_InitStruct->PeriphOrM2MSrcAddress  = 0x00000000U;
00383   DMA_InitStruct->MemoryOrM2MDstAddress  = 0x00000000U;
00384   DMA_InitStruct->Direction              = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
00385   DMA_InitStruct->Mode                   = LL_DMA_MODE_NORMAL;
00386   DMA_InitStruct->PeriphOrM2MSrcIncMode  = LL_DMA_PERIPH_NOINCREMENT;
00387   DMA_InitStruct->MemoryOrM2MDstIncMode  = LL_DMA_MEMORY_NOINCREMENT;
00388   DMA_InitStruct->PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
00389   DMA_InitStruct->MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
00390   DMA_InitStruct->NbData                 = 0x00000000U;
00391 #if defined(DMAMUX1)
00392   DMA_InitStruct->PeriphRequest          = LL_DMAMUX_REQUEST_MEM2MEM;
00393 #else
00394   DMA_InitStruct->PeriphRequest          = LL_DMA_REQUEST_0;
00395 #endif /* DMAMUX1 */
00396   DMA_InitStruct->Priority               = LL_DMA_PRIORITY_LOW;
00397 }
00398 
00399 /**
00400   * @}
00401   */
00402 
00403 /**
00404   * @}
00405   */
00406 
00407 /**
00408   * @}
00409   */
00410 
00411 #endif /* DMA1 || DMA2 */
00412 
00413 /**
00414   * @}
00415   */
00416 
00417 #endif /* USE_FULL_LL_DRIVER */
00418 
00419 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/