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 #if defined(LL_DMA_CHANNEL_5)
78 #define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL)  ((((INSTANCE) == DMA1) && \
79                                                              (((CHANNEL) == LL_DMA_CHANNEL_1) || \
80                                                               ((CHANNEL) == LL_DMA_CHANNEL_2) || \
81                                                               ((CHANNEL) == LL_DMA_CHANNEL_3) || \
82                                                               ((CHANNEL) == LL_DMA_CHANNEL_4) || \
83                                                               ((CHANNEL) == LL_DMA_CHANNEL_5))))
84 #else
85 #define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL)  ((((INSTANCE) == DMA1) && \
86                                                              (((CHANNEL) == LL_DMA_CHANNEL_1) || \
87                                                               ((CHANNEL) == LL_DMA_CHANNEL_2) || \
88                                                               ((CHANNEL) == LL_DMA_CHANNEL_3))))
89 #endif /* LL_DMA_CHANNEL_5 */
90 
91 /**
92   * @}
93   */
94 
95 /* Private function prototypes -----------------------------------------------*/
96 
97 /* Exported functions --------------------------------------------------------*/
98 /** @addtogroup DMA_LL_Exported_Functions
99   * @{
100   */
101 
102 /** @addtogroup DMA_LL_EF_Init
103   * @{
104   */
105 
106 /**
107   * @brief  De-initialize the DMA registers to their default reset values.
108   * @param  DMAx DMAx Instance
109   * @param  Channel This parameter can be one of the following values:
110   *         @arg @ref LL_DMA_CHANNEL_1
111   *         @arg @ref LL_DMA_CHANNEL_2
112   *         @arg @ref LL_DMA_CHANNEL_3
113   *         @arg @ref LL_DMA_CHANNEL_4 (*)
114   *         @arg @ref LL_DMA_CHANNEL_5 (*)
115   *         @arg @ref LL_DMA_CHANNEL_ALL
116   * @note (*) Availability depends on devices
117   * @retval An ErrorStatus enumeration value:
118   *          - SUCCESS: DMA registers are de-initialized
119   *          - ERROR: DMA registers are not de-initialized
120   */
LL_DMA_DeInit(DMA_TypeDef * DMAx,uint32_t Channel)121 ErrorStatus LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel)
122 {
123   ErrorStatus status = SUCCESS;
124 
125   /* Check the DMA Instance DMAx and Channel parameters*/
126   assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel) || (Channel == LL_DMA_CHANNEL_ALL));
127 
128   if (Channel == LL_DMA_CHANNEL_ALL)
129   {
130     if (DMAx == DMA1)
131     {
132       /* Force reset of DMA clock */
133       LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA1);
134 
135       /* Release reset of DMA clock */
136       LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA1);
137     }
138     else
139     {
140       status = ERROR;
141     }
142   }
143   else
144   {
145     DMA_Channel_TypeDef *tmp;
146 
147     tmp = (DMA_Channel_TypeDef *)(__LL_DMA_GET_CHANNEL_INSTANCE(DMAx, Channel));
148 
149     /* Disable the selected DMAx_Channely */
150     CLEAR_BIT(tmp->CCR, DMA_CCR_EN);
151 
152     /* Reset DMAx_Channely control register */
153     WRITE_REG(tmp->CCR, 0U);
154 
155     /* Reset DMAx_Channely remaining bytes register */
156     WRITE_REG(tmp->CNDTR, 0U);
157 
158     /* Reset DMAx_Channely peripheral address register */
159     WRITE_REG(tmp->CPAR, 0U);
160 
161     /* Reset DMAx_Channely memory address register */
162     WRITE_REG(tmp->CMAR, 0U);
163 
164     /* Reset Request register field for DMAx Channel */
165     LL_DMA_SetPeriphRequest(DMAx, Channel, LL_DMAMUX_REQ_MEM2MEM);
166 
167     if (Channel == LL_DMA_CHANNEL_1)
168     {
169       /* Reset interrupt pending bits for DMAx Channel1 */
170       LL_DMA_ClearFlag_GI1(DMAx);
171     }
172     else if (Channel == LL_DMA_CHANNEL_2)
173     {
174       /* Reset interrupt pending bits for DMAx Channel2 */
175       LL_DMA_ClearFlag_GI2(DMAx);
176     }
177     else if (Channel == LL_DMA_CHANNEL_3)
178     {
179       /* Reset interrupt pending bits for DMAx Channel3 */
180       LL_DMA_ClearFlag_GI3(DMAx);
181     }
182 #if defined(DMA1_Channel4)
183     else if (Channel == LL_DMA_CHANNEL_4)
184     {
185       /* Reset interrupt pending bits for DMAx Channel4 */
186       LL_DMA_ClearFlag_GI4(DMAx);
187     }
188     else if (Channel == LL_DMA_CHANNEL_5)
189     {
190       /* Reset interrupt pending bits for DMAx Channel5 */
191       LL_DMA_ClearFlag_GI5(DMAx);
192     }
193 #endif /* DMA1_Channel4 */
194     else
195     {
196       status = ERROR;
197     }
198   }
199 
200   return status;
201 }
202 
203 /**
204   * @brief  Initialize the DMA registers according to the specified parameters in DMA_InitStruct.
205   * @note   To convert DMAx_Channely Instance to DMAx Instance and Channely, use helper macros :
206   *         @arg @ref __LL_DMA_GET_INSTANCE
207   *         @arg @ref __LL_DMA_GET_CHANNEL
208   * @param  DMAx DMAx Instance
209   * @param  Channel This parameter can be one of the following values:
210   *         @arg @ref LL_DMA_CHANNEL_1
211   *         @arg @ref LL_DMA_CHANNEL_2
212   *         @arg @ref LL_DMA_CHANNEL_3
213   *         @arg @ref LL_DMA_CHANNEL_4 (*)
214   *         @arg @ref LL_DMA_CHANNEL_5 (*)
215   * @note (*) Availability depends on devices
216   * @param  DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure.
217   * @retval An ErrorStatus enumeration value:
218   *          - SUCCESS: DMA registers are initialized
219   *          - ERROR: Not applicable
220   */
LL_DMA_Init(DMA_TypeDef * DMAx,uint32_t Channel,LL_DMA_InitTypeDef * DMA_InitStruct)221 ErrorStatus LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitTypeDef *DMA_InitStruct)
222 {
223   /* Check the DMA Instance DMAx and Channel parameters*/
224   assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel));
225 
226   /* Check the DMA parameters from DMA_InitStruct */
227   assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction));
228   assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode));
229   assert_param(IS_LL_DMA_PERIPHINCMODE(DMA_InitStruct->PeriphOrM2MSrcIncMode));
230   assert_param(IS_LL_DMA_MEMORYINCMODE(DMA_InitStruct->MemoryOrM2MDstIncMode));
231   assert_param(IS_LL_DMA_PERIPHDATASIZE(DMA_InitStruct->PeriphOrM2MSrcDataSize));
232   assert_param(IS_LL_DMA_MEMORYDATASIZE(DMA_InitStruct->MemoryOrM2MDstDataSize));
233   assert_param(IS_LL_DMA_NBDATA(DMA_InitStruct->NbData));
234   assert_param(IS_LL_DMA_PERIPHREQUEST(DMA_InitStruct->PeriphRequest));
235   assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority));
236 
237   /*---------------------------- DMAx CCR Configuration ------------------------
238    * Configure DMAx_Channely: data transfer direction, data transfer mode,
239    *                          peripheral and memory increment mode,
240    *                          data size alignment and  priority level with parameters :
241    * - Direction:      DMA_CCR_DIR and DMA_CCR_MEM2MEM bits
242    * - Mode:           DMA_CCR_CIRC bit
243    * - PeriphOrM2MSrcIncMode:  DMA_CCR_PINC bit
244    * - MemoryOrM2MDstIncMode:  DMA_CCR_MINC bit
245    * - PeriphOrM2MSrcDataSize: DMA_CCR_PSIZE[1:0] bits
246    * - MemoryOrM2MDstDataSize: DMA_CCR_MSIZE[1:0] bits
247    * - Priority:               DMA_CCR_PL[1:0] bits
248    */
249   LL_DMA_ConfigTransfer(DMAx, Channel, DMA_InitStruct->Direction              | \
250                         DMA_InitStruct->Mode                   | \
251                         DMA_InitStruct->PeriphOrM2MSrcIncMode  | \
252                         DMA_InitStruct->MemoryOrM2MDstIncMode  | \
253                         DMA_InitStruct->PeriphOrM2MSrcDataSize | \
254                         DMA_InitStruct->MemoryOrM2MDstDataSize | \
255                         DMA_InitStruct->Priority);
256 
257   /*-------------------------- DMAx CMAR Configuration -------------------------
258    * Configure the memory or destination base address with parameter :
259    * - MemoryOrM2MDstAddress: DMA_CMAR_MA[31:0] bits
260    */
261   LL_DMA_SetMemoryAddress(DMAx, Channel, DMA_InitStruct->MemoryOrM2MDstAddress);
262 
263   /*-------------------------- DMAx CPAR Configuration -------------------------
264    * Configure the peripheral or source base address with parameter :
265    * - PeriphOrM2MSrcAddress: DMA_CPAR_PA[31:0] bits
266    */
267   LL_DMA_SetPeriphAddress(DMAx, Channel, DMA_InitStruct->PeriphOrM2MSrcAddress);
268 
269   /*--------------------------- DMAx CNDTR Configuration -----------------------
270    * Configure the peripheral base address with parameter :
271    * - NbData: DMA_CNDTR_NDT[15:0] bits
272    */
273   LL_DMA_SetDataLength(DMAx, Channel, DMA_InitStruct->NbData);
274 
275   /*--------------------------- DMAMUXx CCR Configuration ----------------------
276    * Configure the DMA request for DMA Channels on DMAMUX Channel x with parameter :
277    * - PeriphRequest: DMA_CxCR[7:0] bits
278    */
279   LL_DMA_SetPeriphRequest(DMAx, Channel, DMA_InitStruct->PeriphRequest);
280 
281   return SUCCESS;
282 }
283 
284 /**
285   * @brief  Set each @ref LL_DMA_InitTypeDef field to default value.
286   * @param  DMA_InitStruct Pointer to a @ref LL_DMA_InitTypeDef structure.
287   * @retval None
288   */
LL_DMA_StructInit(LL_DMA_InitTypeDef * DMA_InitStruct)289 void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct)
290 {
291   /* Set DMA_InitStruct fields to default values */
292   DMA_InitStruct->PeriphOrM2MSrcAddress  = 0x00000000U;
293   DMA_InitStruct->MemoryOrM2MDstAddress  = 0x00000000U;
294   DMA_InitStruct->Direction              = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
295   DMA_InitStruct->Mode                   = LL_DMA_MODE_NORMAL;
296   DMA_InitStruct->PeriphOrM2MSrcIncMode  = LL_DMA_PERIPH_NOINCREMENT;
297   DMA_InitStruct->MemoryOrM2MDstIncMode  = LL_DMA_MEMORY_NOINCREMENT;
298   DMA_InitStruct->PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
299   DMA_InitStruct->MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
300   DMA_InitStruct->NbData                 = 0x00000000U;
301   DMA_InitStruct->PeriphRequest          = LL_DMAMUX_REQ_MEM2MEM;
302   DMA_InitStruct->Priority               = LL_DMA_PRIORITY_LOW;
303 }
304 
305 /**
306   * @}
307   */
308 
309 /**
310   * @}
311   */
312 
313 /**
314   * @}
315   */
316 
317 #endif /* DMA1 */
318 
319 /**
320   * @}
321   */
322 
323 #endif /* USE_FULL_LL_DRIVER */
324