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