1 /**
2   ******************************************************************************
3   * @file    stm32c0xx_ll_dma.c
4   * @author  MCD Application Team
5   * @brief   DMA LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2022 STMicroelectronics.
10   * All rights reserved.
11   *
12   * This software is licensed under terms that can be found in the LICENSE file
13   * in the root directory of this software component.
14   * If no LICENSE file comes with this software, it is provided AS-IS.
15   *
16   ******************************************************************************
17   */
18 #if defined(USE_FULL_LL_DRIVER)
19 
20 /* Includes ------------------------------------------------------------------*/
21 #include "stm32c0xx_ll_dma.h"
22 #include "stm32c0xx_ll_bus.h"
23 #ifdef  USE_FULL_ASSERT
24 #include "stm32_assert.h"
25 #else
26 #define assert_param(expr) ((void)0U)
27 #endif /* USE_FULL_ASSERT */
28 
29 /** @addtogroup STM32C0xx_LL_Driver
30   * @{
31   */
32 
33 #if defined (DMA1)
34 
35 /** @defgroup DMA_LL DMA
36   * @{
37   */
38 
39 /* Private types -------------------------------------------------------------*/
40 /* Private variables ---------------------------------------------------------*/
41 /* Private constants ---------------------------------------------------------*/
42 /* Private macros ------------------------------------------------------------*/
43 /** @addtogroup DMA_LL_Private_Macros
44   * @{
45   */
46 #define IS_LL_DMA_DIRECTION(__VALUE__)          (((__VALUE__) == LL_DMA_DIRECTION_PERIPH_TO_MEMORY) || \
47                                                  ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_PERIPH) || \
48                                                  ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_MEMORY))
49 
50 #define IS_LL_DMA_MODE(__VALUE__)               (((__VALUE__) == LL_DMA_MODE_NORMAL) || \
51                                                  ((__VALUE__) == LL_DMA_MODE_CIRCULAR))
52 
53 #define IS_LL_DMA_PERIPHINCMODE(__VALUE__)      (((__VALUE__) == LL_DMA_PERIPH_INCREMENT) || \
54                                                  ((__VALUE__) == LL_DMA_PERIPH_NOINCREMENT))
55 
56 #define IS_LL_DMA_MEMORYINCMODE(__VALUE__)      (((__VALUE__) == LL_DMA_MEMORY_INCREMENT) || \
57                                                  ((__VALUE__) == LL_DMA_MEMORY_NOINCREMENT))
58 
59 #define IS_LL_DMA_PERIPHDATASIZE(__VALUE__)     (((__VALUE__) == LL_DMA_PDATAALIGN_BYTE)      || \
60                                                  ((__VALUE__) == LL_DMA_PDATAALIGN_HALFWORD)  || \
61                                                  ((__VALUE__) == LL_DMA_PDATAALIGN_WORD))
62 
63 #define IS_LL_DMA_MEMORYDATASIZE(__VALUE__)     (((__VALUE__) == LL_DMA_MDATAALIGN_BYTE)      || \
64                                                  ((__VALUE__) == LL_DMA_MDATAALIGN_HALFWORD)  || \
65                                                  ((__VALUE__) == LL_DMA_MDATAALIGN_WORD))
66 
67 #define IS_LL_DMA_NBDATA(__VALUE__)             ((__VALUE__)  <= 0x0000FFFFU)
68 
69 
70 #define IS_LL_DMA_PERIPHREQUEST(__VALUE__)      ((__VALUE__) <= LL_DMAMUX_REQ_USART2_TX)
71 
72 #define IS_LL_DMA_PRIORITY(__VALUE__)           (((__VALUE__) == LL_DMA_PRIORITY_LOW)    || \
73                                                  ((__VALUE__) == LL_DMA_PRIORITY_MEDIUM) || \
74                                                  ((__VALUE__) == LL_DMA_PRIORITY_HIGH)   || \
75                                                  ((__VALUE__) == LL_DMA_PRIORITY_VERYHIGH))
76 
77 #define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL)  ((((INSTANCE) == DMA1) && \
78                                                              (((CHANNEL) == LL_DMA_CHANNEL_1) || \
79                                                               ((CHANNEL) == LL_DMA_CHANNEL_2) || \
80                                                               ((CHANNEL) == LL_DMA_CHANNEL_3))))
81 
82 /**
83   * @}
84   */
85 
86 /* Private function prototypes -----------------------------------------------*/
87 
88 /* Exported functions --------------------------------------------------------*/
89 /** @addtogroup DMA_LL_Exported_Functions
90   * @{
91   */
92 
93 /** @addtogroup DMA_LL_EF_Init
94   * @{
95   */
96 
97 /**
98   * @brief  De-initialize the DMA registers to their default reset values.
99   * @param  DMAx DMAx Instance
100   * @param  Channel This parameter can be one of the following values:
101   *         @arg @ref LL_DMA_CHANNEL_1
102   *         @arg @ref LL_DMA_CHANNEL_2
103   *         @arg @ref LL_DMA_CHANNEL_3
104   *         @arg @ref LL_DMA_CHANNEL_ALL
105   * @retval An ErrorStatus enumeration value:
106   *          - SUCCESS: DMA registers are de-initialized
107   *          - ERROR: DMA registers are not de-initialized
108   */
LL_DMA_DeInit(DMA_TypeDef * DMAx,uint32_t Channel)109 ErrorStatus LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel)
110 {
111   ErrorStatus status = SUCCESS;
112 
113   /* Check the DMA Instance DMAx and Channel parameters*/
114   assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel) || (Channel == LL_DMA_CHANNEL_ALL));
115 
116   if (Channel == LL_DMA_CHANNEL_ALL)
117   {
118     if (DMAx == DMA1)
119     {
120       /* Force reset of DMA clock */
121       LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA1);
122 
123       /* Release reset of DMA clock */
124       LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA1);
125     }
126     else
127     {
128       status = ERROR;
129     }
130   }
131   else
132   {
133     DMA_Channel_TypeDef *tmp;
134 
135     tmp = (DMA_Channel_TypeDef *)(__LL_DMA_GET_CHANNEL_INSTANCE(DMAx, Channel));
136 
137     /* Disable the selected DMAx_Channely */
138     CLEAR_BIT(tmp->CCR, DMA_CCR_EN);
139 
140     /* Reset DMAx_Channely control register */
141     WRITE_REG(tmp->CCR, 0U);
142 
143     /* Reset DMAx_Channely remaining bytes register */
144     WRITE_REG(tmp->CNDTR, 0U);
145 
146     /* Reset DMAx_Channely peripheral address register */
147     WRITE_REG(tmp->CPAR, 0U);
148 
149     /* Reset DMAx_Channely memory address register */
150     WRITE_REG(tmp->CMAR, 0U);
151 
152     /* Reset Request register field for DMAx Channel */
153     LL_DMA_SetPeriphRequest(DMAx, Channel, LL_DMAMUX_REQ_MEM2MEM);
154 
155     if (Channel == LL_DMA_CHANNEL_1)
156     {
157       /* Reset interrupt pending bits for DMAx Channel1 */
158       LL_DMA_ClearFlag_GI1(DMAx);
159     }
160     else if (Channel == LL_DMA_CHANNEL_2)
161     {
162       /* Reset interrupt pending bits for DMAx Channel2 */
163       LL_DMA_ClearFlag_GI2(DMAx);
164     }
165     else if (Channel == LL_DMA_CHANNEL_3)
166     {
167       /* Reset interrupt pending bits for DMAx Channel3 */
168       LL_DMA_ClearFlag_GI3(DMAx);
169     }
170     else
171     {
172       status = ERROR;
173     }
174   }
175 
176   return status;
177 }
178 
179 /**
180   * @brief  Initialize the DMA registers according to the specified parameters in DMA_InitStruct.
181   * @note   To convert DMAx_Channely Instance to DMAx Instance and Channely, use helper macros :
182   *         @arg @ref __LL_DMA_GET_INSTANCE
183   *         @arg @ref __LL_DMA_GET_CHANNEL
184   * @param  DMAx DMAx Instance
185   * @param  Channel This parameter can be one of the following values:
186   *         @arg @ref LL_DMA_CHANNEL_1
187   *         @arg @ref LL_DMA_CHANNEL_2
188   *         @arg @ref LL_DMA_CHANNEL_3
189   * @param  DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure.
190   * @retval An ErrorStatus enumeration value:
191   *          - SUCCESS: DMA registers are initialized
192   *          - ERROR: Not applicable
193   */
LL_DMA_Init(DMA_TypeDef * DMAx,uint32_t Channel,LL_DMA_InitTypeDef * DMA_InitStruct)194 ErrorStatus LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitTypeDef *DMA_InitStruct)
195 {
196   /* Check the DMA Instance DMAx and Channel parameters*/
197   assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel));
198 
199   /* Check the DMA parameters from DMA_InitStruct */
200   assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction));
201   assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode));
202   assert_param(IS_LL_DMA_PERIPHINCMODE(DMA_InitStruct->PeriphOrM2MSrcIncMode));
203   assert_param(IS_LL_DMA_MEMORYINCMODE(DMA_InitStruct->MemoryOrM2MDstIncMode));
204   assert_param(IS_LL_DMA_PERIPHDATASIZE(DMA_InitStruct->PeriphOrM2MSrcDataSize));
205   assert_param(IS_LL_DMA_MEMORYDATASIZE(DMA_InitStruct->MemoryOrM2MDstDataSize));
206   assert_param(IS_LL_DMA_NBDATA(DMA_InitStruct->NbData));
207   assert_param(IS_LL_DMA_PERIPHREQUEST(DMA_InitStruct->PeriphRequest));
208   assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority));
209 
210   /*---------------------------- DMAx CCR Configuration ------------------------
211    * Configure DMAx_Channely: data transfer direction, data transfer mode,
212    *                          peripheral and memory increment mode,
213    *                          data size alignment and  priority level with parameters :
214    * - Direction:      DMA_CCR_DIR and DMA_CCR_MEM2MEM bits
215    * - Mode:           DMA_CCR_CIRC bit
216    * - PeriphOrM2MSrcIncMode:  DMA_CCR_PINC bit
217    * - MemoryOrM2MDstIncMode:  DMA_CCR_MINC bit
218    * - PeriphOrM2MSrcDataSize: DMA_CCR_PSIZE[1:0] bits
219    * - MemoryOrM2MDstDataSize: DMA_CCR_MSIZE[1:0] bits
220    * - Priority:               DMA_CCR_PL[1:0] bits
221    */
222   LL_DMA_ConfigTransfer(DMAx, Channel, DMA_InitStruct->Direction              | \
223                         DMA_InitStruct->Mode                   | \
224                         DMA_InitStruct->PeriphOrM2MSrcIncMode  | \
225                         DMA_InitStruct->MemoryOrM2MDstIncMode  | \
226                         DMA_InitStruct->PeriphOrM2MSrcDataSize | \
227                         DMA_InitStruct->MemoryOrM2MDstDataSize | \
228                         DMA_InitStruct->Priority);
229 
230   /*-------------------------- DMAx CMAR Configuration -------------------------
231    * Configure the memory or destination base address with parameter :
232    * - MemoryOrM2MDstAddress: DMA_CMAR_MA[31:0] bits
233    */
234   LL_DMA_SetMemoryAddress(DMAx, Channel, DMA_InitStruct->MemoryOrM2MDstAddress);
235 
236   /*-------------------------- DMAx CPAR Configuration -------------------------
237    * Configure the peripheral or source base address with parameter :
238    * - PeriphOrM2MSrcAddress: DMA_CPAR_PA[31:0] bits
239    */
240   LL_DMA_SetPeriphAddress(DMAx, Channel, DMA_InitStruct->PeriphOrM2MSrcAddress);
241 
242   /*--------------------------- DMAx CNDTR Configuration -----------------------
243    * Configure the peripheral base address with parameter :
244    * - NbData: DMA_CNDTR_NDT[15:0] bits
245    */
246   LL_DMA_SetDataLength(DMAx, Channel, DMA_InitStruct->NbData);
247 
248   /*--------------------------- DMAMUXx CCR Configuration ----------------------
249    * Configure the DMA request for DMA Channels on DMAMUX Channel x with parameter :
250    * - PeriphRequest: DMA_CxCR[7:0] bits
251    */
252   LL_DMA_SetPeriphRequest(DMAx, Channel, DMA_InitStruct->PeriphRequest);
253 
254   return SUCCESS;
255 }
256 
257 /**
258   * @brief  Set each @ref LL_DMA_InitTypeDef field to default value.
259   * @param  DMA_InitStruct Pointer to a @ref LL_DMA_InitTypeDef structure.
260   * @retval None
261   */
LL_DMA_StructInit(LL_DMA_InitTypeDef * DMA_InitStruct)262 void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct)
263 {
264   /* Set DMA_InitStruct fields to default values */
265   DMA_InitStruct->PeriphOrM2MSrcAddress  = 0x00000000U;
266   DMA_InitStruct->MemoryOrM2MDstAddress  = 0x00000000U;
267   DMA_InitStruct->Direction              = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
268   DMA_InitStruct->Mode                   = LL_DMA_MODE_NORMAL;
269   DMA_InitStruct->PeriphOrM2MSrcIncMode  = LL_DMA_PERIPH_NOINCREMENT;
270   DMA_InitStruct->MemoryOrM2MDstIncMode  = LL_DMA_MEMORY_NOINCREMENT;
271   DMA_InitStruct->PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
272   DMA_InitStruct->MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
273   DMA_InitStruct->NbData                 = 0x00000000U;
274   DMA_InitStruct->PeriphRequest          = LL_DMAMUX_REQ_MEM2MEM;
275   DMA_InitStruct->Priority               = LL_DMA_PRIORITY_LOW;
276 }
277 
278 /**
279   * @}
280   */
281 
282 /**
283   * @}
284   */
285 
286 /**
287   * @}
288   */
289 
290 #endif /* DMA1 */
291 
292 /**
293   * @}
294   */
295 
296 #endif /* USE_FULL_LL_DRIVER */
297