1 /**
2 ******************************************************************************
3 * @file stm32h5xx_ll_dma.c
4 * @author MCD Application Team
5 * @brief DMA LL module driver.
6 ******************************************************************************
7 * @attention
8 *
9 * Copyright (c) 2023 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 @verbatim
18 ==============================================================================
19 ##### LL DMA driver acronyms #####
20 ==============================================================================
21 [..] Acronyms table :
22 =========================================
23 || Acronym || ||
24 =========================================
25 || SRC || Source ||
26 || DEST || Destination ||
27 || ADDR || Address ||
28 || ADDRS || Addresses ||
29 || INC || Increment / Incremented ||
30 || DEC || Decrement / Decremented ||
31 || BLK || Block ||
32 || RPT || Repeat / Repeated ||
33 || TRIG || Trigger ||
34 =========================================
35 @endverbatim
36 ******************************************************************************
37 */
38
39 #if defined (USE_FULL_LL_DRIVER)
40
41 /* Includes ------------------------------------------------------------------*/
42 #include "stm32h5xx_ll_dma.h"
43 #include "stm32h5xx_ll_bus.h"
44 #ifdef USE_FULL_ASSERT
45 #include "stm32_assert.h"
46 #else
47 #define assert_param(expr) ((void)0U)
48 #endif /* USE_FULL_ASSERT */
49
50 /** @addtogroup STM32H5xx_LL_Driver
51 * @{
52 */
53
54 #if defined (GPDMA1)
55
56 /** @addtogroup DMA_LL
57 * @{
58 */
59
60 /* Private types -------------------------------------------------------------*/
61 /* Private variables ---------------------------------------------------------*/
62 /* Private constants ---------------------------------------------------------*/
63 /* Private macros ------------------------------------------------------------*/
64
65 /** @addtogroup DMA_LL_Private_Macros
66 * @{
67 */
68 #define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, Channel) ((((INSTANCE) == GPDMA1) && \
69 (((Channel) == LL_DMA_CHANNEL_0) || \
70 ((Channel) == LL_DMA_CHANNEL_1) || \
71 ((Channel) == LL_DMA_CHANNEL_2) || \
72 ((Channel) == LL_DMA_CHANNEL_3) || \
73 ((Channel) == LL_DMA_CHANNEL_4) || \
74 ((Channel) == LL_DMA_CHANNEL_5) || \
75 ((Channel) == LL_DMA_CHANNEL_6) || \
76 ((Channel) == LL_DMA_CHANNEL_7) || \
77 ((Channel) == LL_DMA_CHANNEL_ALL))) || \
78 (((INSTANCE) == GPDMA2) && \
79 (((Channel) == LL_DMA_CHANNEL_0) || \
80 ((Channel) == LL_DMA_CHANNEL_1) || \
81 ((Channel) == LL_DMA_CHANNEL_2) || \
82 ((Channel) == LL_DMA_CHANNEL_3) || \
83 ((Channel) == LL_DMA_CHANNEL_4) || \
84 ((Channel) == LL_DMA_CHANNEL_5) || \
85 ((Channel) == LL_DMA_CHANNEL_6) || \
86 ((Channel) == LL_DMA_CHANNEL_7) || \
87 ((Channel) == LL_DMA_CHANNEL_ALL))))
88
89 #define IS_LL_GPDMA_CHANNEL_INSTANCE(INSTANCE, Channel) ((((INSTANCE) == GPDMA1) && \
90 (((Channel) == LL_DMA_CHANNEL_0) || \
91 ((Channel) == LL_DMA_CHANNEL_1) || \
92 ((Channel) == LL_DMA_CHANNEL_2) || \
93 ((Channel) == LL_DMA_CHANNEL_3) || \
94 ((Channel) == LL_DMA_CHANNEL_4) || \
95 ((Channel) == LL_DMA_CHANNEL_5) || \
96 ((Channel) == LL_DMA_CHANNEL_6) || \
97 ((Channel) == LL_DMA_CHANNEL_7))) || \
98 (((INSTANCE) == GPDMA2) && \
99 (((Channel) == LL_DMA_CHANNEL_0) || \
100 ((Channel) == LL_DMA_CHANNEL_1) || \
101 ((Channel) == LL_DMA_CHANNEL_2) || \
102 ((Channel) == LL_DMA_CHANNEL_3) || \
103 ((Channel) == LL_DMA_CHANNEL_4) || \
104 ((Channel) == LL_DMA_CHANNEL_5) || \
105 ((Channel) == LL_DMA_CHANNEL_6) || \
106 ((Channel) == LL_DMA_CHANNEL_7))))
107
108 #define IS_LL_DMA_2D_CHANNEL_INSTANCE(INSTANCE, Channel) ((((INSTANCE) == GPDMA1) && \
109 (((Channel) == LL_DMA_CHANNEL_6) || \
110 ((Channel) == LL_DMA_CHANNEL_7))) || \
111 (((INSTANCE) == GPDMA2) && \
112 (((Channel) == LL_DMA_CHANNEL_6) || \
113 ((Channel) == LL_DMA_CHANNEL_7))))
114
115 #define IS_LL_DMA_MODE(__VALUE__) (((__VALUE__) == LL_DMA_NORMAL) || \
116 ((__VALUE__) == LL_DMA_PFCTRL))
117
118 #define IS_LL_DMA_PFREQ_INSTANCE(INSTANCE, Channel) ((((INSTANCE) == GPDMA1) && \
119 (((Channel) == LL_DMA_CHANNEL_0) || \
120 ((Channel) == LL_DMA_CHANNEL_7))) || \
121 (((INSTANCE) == GPDMA2) && \
122 (((Channel) == LL_DMA_CHANNEL_0) || \
123 ((Channel) == LL_DMA_CHANNEL_7))))
124
125 #define IS_LL_DMA_DIRECTION(__VALUE__) (((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_MEMORY) || \
126 ((__VALUE__) == LL_DMA_DIRECTION_PERIPH_TO_MEMORY) || \
127 ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_PERIPH))
128
129 #define IS_LL_DMA_DATA_ALIGNMENT(__VALUE__) (((__VALUE__) == LL_DMA_DATA_ALIGN_ZEROPADD) || \
130 ((__VALUE__) == LL_DMA_DATA_ALIGN_SIGNEXTPADD) || \
131 ((__VALUE__) == LL_DMA_DATA_PACK_UNPACK))
132
133 #define IS_LL_DMA_BURST_LENGTH(__VALUE__) (((__VALUE__) > 0U) && ((__VALUE__) <= 64U))
134
135 #define IS_LL_DMA_SRC_DATA_WIDTH(__VALUE__) (((__VALUE__) == LL_DMA_SRC_DATAWIDTH_BYTE) || \
136 ((__VALUE__) == LL_DMA_SRC_DATAWIDTH_HALFWORD) || \
137 ((__VALUE__) == LL_DMA_SRC_DATAWIDTH_WORD))
138
139 #define IS_LL_DMA_DEST_DATA_WIDTH(__VALUE__) (((__VALUE__) == LL_DMA_DEST_DATAWIDTH_BYTE) || \
140 ((__VALUE__) == LL_DMA_DEST_DATAWIDTH_HALFWORD) || \
141 ((__VALUE__) == LL_DMA_DEST_DATAWIDTH_WORD))
142
143 #define IS_LL_DMA_SRC_INCREMENT_MODE(__VALUE__) (((__VALUE__) == LL_DMA_SRC_FIXED) || \
144 ((__VALUE__) == LL_DMA_SRC_INCREMENT))
145
146 #define IS_LL_DMA_DEST_INCREMENT_MODE(__VALUE__) (((__VALUE__) == LL_DMA_DEST_FIXED) || \
147 ((__VALUE__) == LL_DMA_DEST_INCREMENT))
148
149 #define IS_LL_DMA_PRIORITY(__VALUE__) (((__VALUE__) == LL_DMA_LOW_PRIORITY_LOW_WEIGHT) || \
150 ((__VALUE__) == LL_DMA_LOW_PRIORITY_MID_WEIGHT) || \
151 ((__VALUE__) == LL_DMA_LOW_PRIORITY_HIGH_WEIGHT) || \
152 ((__VALUE__) == LL_DMA_HIGH_PRIORITY))
153
154 #define IS_LL_DMA_BLK_DATALENGTH(__VALUE__) ((__VALUE__) <= 0xFFFFU)
155
156 #define IS_LL_DMA_BLK_REPEATCOUNT(__VALUE__) ((__VALUE__) <= 0x0EFFU)
157
158 #define IS_LL_DMA_TRIGGER_MODE(__VALUE__) (((__VALUE__) == LL_DMA_TRIGM_BLK_TRANSFER) || \
159 ((__VALUE__) == LL_DMA_TRIGM_RPT_BLK_TRANSFER) || \
160 ((__VALUE__) == LL_DMA_TRIGM_LLI_LINK_TRANSFER) || \
161 ((__VALUE__) == LL_DMA_TRIGM_SINGLBURST_TRANSFER ))
162
163 #define IS_LL_DMA_TRIGGER_POLARITY(__VALUE__) (((__VALUE__) == LL_DMA_TRIG_POLARITY_MASKED) || \
164 ((__VALUE__) == LL_DMA_TRIG_POLARITY_RISING) || \
165 ((__VALUE__) == LL_DMA_TRIG_POLARITY_FALLING))
166
167 #define IS_LL_DMA_BLKHW_REQUEST(__VALUE__) (((__VALUE__) == LL_DMA_HWREQUEST_SINGLEBURST) || \
168 ((__VALUE__) == LL_DMA_HWREQUEST_BLK))
169
170 #if defined (I3C2)
171 #define IS_LL_DMA_TRIGGER_SELECTION(__VALUE__) ((__VALUE__) <= LL_GPDMA1_TRIGGER_EVENTOUT)
172 #else
173 #define IS_LL_DMA_TRIGGER_SELECTION(__VALUE__) ((__VALUE__) <= LL_GPDMA1_TRIGGER_LPTIM6_CH2)
174 #endif /* I3C2 */
175
176 #if defined (I3C2)
177 #define IS_LL_DMA_REQUEST_SELECTION(__VALUE__) ((__VALUE__) <= LL_GPDMA1_REQUEST_I3C2_RS)
178 #else
179 #define IS_LL_DMA_REQUEST_SELECTION(__VALUE__) ((__VALUE__) <= LL_GPDMA1_REQUEST_LPTIM6_UE)
180 #endif /* I3C2 */
181
182 #define IS_LL_DMA_TRANSFER_EVENT_MODE(__VALUE__) (((__VALUE__) == LL_DMA_TCEM_BLK_TRANSFER) || \
183 ((__VALUE__) == LL_DMA_TCEM_RPT_BLK_TRANSFER) || \
184 ((__VALUE__) == LL_DMA_TCEM_EACH_LLITEM_TRANSFER) || \
185 ((__VALUE__) == LL_DMA_TCEM_LAST_LLITEM_TRANSFER))
186
187 #define IS_LL_DMA_DEST_HALFWORD_EXCHANGE(__VALUE__) (((__VALUE__) == LL_DMA_DEST_HALFWORD_PRESERVE) || \
188 ((__VALUE__) == LL_DMA_DEST_HALFWORD_EXCHANGE))
189
190 #define IS_LL_DMA_DEST_BYTE_EXCHANGE(__VALUE__) (((__VALUE__) == LL_DMA_DEST_BYTE_PRESERVE) || \
191 ((__VALUE__) == LL_DMA_DEST_BYTE_EXCHANGE))
192
193 #define IS_LL_DMA_SRC_BYTE_EXCHANGE(__VALUE__) (((__VALUE__) == LL_DMA_SRC_BYTE_PRESERVE) || \
194 ((__VALUE__) == LL_DMA_SRC_BYTE_EXCHANGE))
195
196 #define IS_LL_DMA_LINK_ALLOCATED_PORT(__VALUE__) (((__VALUE__) == LL_DMA_LINK_ALLOCATED_PORT0) || \
197 ((__VALUE__) == LL_DMA_LINK_ALLOCATED_PORT1))
198
199 #define IS_LL_DMA_SRC_ALLOCATED_PORT(__VALUE__) (((__VALUE__) == LL_DMA_SRC_ALLOCATED_PORT0) || \
200 ((__VALUE__) == LL_DMA_SRC_ALLOCATED_PORT1))
201
202 #define IS_LL_DMA_DEST_ALLOCATED_PORT(__VALUE__) (((__VALUE__) == LL_DMA_DEST_ALLOCATED_PORT0) || \
203 ((__VALUE__) == LL_DMA_DEST_ALLOCATED_PORT1))
204
205 #define IS_LL_DMA_LINK_STEP_MODE(__VALUE__) (((__VALUE__) == LL_DMA_LSM_FULL_EXECUTION) || \
206 ((__VALUE__) == LL_DMA_LSM_1LINK_EXECUTION))
207
208 #define IS_LL_DMA_BURST_SRC_ADDR_UPDATE(__VALUE__) (((__VALUE__) == LL_DMA_BURST_SRC_ADDR_INCREMENT) || \
209 ((__VALUE__) == LL_DMA_BURST_SRC_ADDR_DECREMENT))
210
211 #define IS_LL_DMA_BURST_DEST_ADDR_UPDATE(__VALUE__) (((__VALUE__) == LL_DMA_BURST_DEST_ADDR_INCREMENT) || \
212 ((__VALUE__) == LL_DMA_BURST_DEST_ADDR_DECREMENT))
213
214 #define IS_LL_DMA_BURST_ADDR_UPDATE_VALUE(__VALUE__) ((__VALUE__) <= 0x1FFFU)
215
216 #define IS_LL_DMA_BLKRPT_SRC_ADDR_UPDATE(__VALUE__) (((__VALUE__) == LL_DMA_BLKRPT_SRC_ADDR_INCREMENT) || \
217 ((__VALUE__) == LL_DMA_BLKRPT_SRC_ADDR_DECREMENT))
218
219 #define IS_LL_DMA_BLKRPT_DEST_ADDR_UPDATE(__VALUE__) (((__VALUE__) == LL_DMA_BLKRPT_DEST_ADDR_INCREMENT) || \
220 ((__VALUE__) == LL_DMA_BLKRPT_DEST_ADDR_DECREMENT))
221
222 #define IS_LL_DMA_BLKRPT_ADDR_UPDATE_VALUE(__VALUE__) ((__VALUE__) <= 0xFFFFU)
223
224 #define IS_LL_DMA_LINK_BASEADDR(__VALUE__) (((__VALUE__) & 0xFFFFU) == 0U)
225
226 #define IS_LL_DMA_LINK_ADDR_OFFSET(__VALUE__) (((__VALUE__) & 0x03U) == 0U)
227
228 #define IS_LL_DMA_LINK_UPDATE_REGISTERS(__VALUE__) ((((__VALUE__) & 0x01FE0000U) == 0U) && ((__VALUE__) != 0U))
229
230 #define IS_LL_DMA_LINK_NODETYPE(__VALUE__) (((__VALUE__) == LL_DMA_GPDMA_2D_NODE) || \
231 ((__VALUE__) == LL_DMA_GPDMA_LINEAR_NODE))
232
233 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
234 #define IS_LL_DMA_CHANNEL_SRC_SEC(__VALUE__) (((__VALUE__) == LL_DMA_CHANNEL_SRC_NSEC) || \
235 ((__VALUE__) == LL_DMA_CHANNEL_SRC_SEC))
236
237 #define IS_LL_DMA_CHANNEL_DEST_SEC(__VALUE__) (((__VALUE__) == LL_DMA_CHANNEL_DEST_NSEC) || \
238 ((__VALUE__) == LL_DMA_CHANNEL_DEST_SEC))
239
240 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
241 /**
242 * @}
243 */
244
245 /* Private function prototypes -----------------------------------------------*/
246 /* Exported functions --------------------------------------------------------*/
247
248 /** @addtogroup DMA_LL_Exported_Functions
249 * @{
250 */
251
252 /** @addtogroup DMA_LL_EF_Init
253 * @{
254 */
255
256 /**
257 * @brief De-initialize the DMA registers to their default reset values.
258 * @note This API is used for all available DMA channels.
259 * @note To convert DMAx_Channely Instance to DMAx Instance and Channely, use
260 * helper macros :
261 * @arg @ref LL_DMA_GET_INSTANCE
262 * @arg @ref LL_DMA_GET_CHANNEL
263 * @param DMAx DMAx Instance
264 * @param Channel This parameter can be one of the following values:
265 * @arg @ref LL_DMA_CHANNEL_0
266 * @arg @ref LL_DMA_CHANNEL_1
267 * @arg @ref LL_DMA_CHANNEL_2
268 * @arg @ref LL_DMA_CHANNEL_3
269 * @arg @ref LL_DMA_CHANNEL_4
270 * @arg @ref LL_DMA_CHANNEL_5
271 * @arg @ref LL_DMA_CHANNEL_6
272 * @arg @ref LL_DMA_CHANNEL_7
273 * @retval An ErrorStatus enumeration value:
274 * - SUCCESS : DMA registers are de-initialized.
275 * - ERROR : DMA registers are not de-initialized.
276 */
LL_DMA_DeInit(DMA_TypeDef * DMAx,uint32_t Channel)277 uint32_t LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel)
278 {
279 DMA_Channel_TypeDef *tmp;
280 ErrorStatus status = SUCCESS;
281
282 /* Check the DMA Instance DMAx and Channel parameters */
283 assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel));
284
285 if (Channel == LL_DMA_CHANNEL_ALL)
286 {
287 if (DMAx == GPDMA1)
288 {
289 /* Force reset of DMA clock */
290 LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_GPDMA1);
291
292 /* Release reset of DMA clock */
293 LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_GPDMA1);
294 }
295 else
296 {
297 /* Force reset of DMA clock */
298 LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_GPDMA2);
299
300 /* Release reset of DMA clock */
301 LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_GPDMA2);
302 }
303 }
304 else
305 {
306 /* Get the DMA Channel Instance */
307 tmp = (DMA_Channel_TypeDef *)(LL_DMA_GET_CHANNEL_INSTANCE(DMAx, Channel));
308
309 /* Suspend DMA channel */
310 LL_DMA_SuspendChannel(DMAx, Channel);
311
312 /* Disable the selected Channel */
313 LL_DMA_ResetChannel(DMAx, Channel);
314
315 /* Reset DMAx_Channely control register */
316 LL_DMA_WriteReg(tmp, CLBAR, 0U);
317
318 /* Reset DMAx_Channely control register */
319 LL_DMA_WriteReg(tmp, CCR, 0U);
320
321 /* Reset DMAx_Channely Configuration register */
322 LL_DMA_WriteReg(tmp, CTR1, 0U);
323
324 /* Reset DMAx_Channely transfer register 2 */
325 LL_DMA_WriteReg(tmp, CTR2, 0U);
326
327 /* Reset DMAx_Channely block number of data register */
328 LL_DMA_WriteReg(tmp, CBR1, 0U);
329
330 /* Reset DMAx_Channely source address register */
331 LL_DMA_WriteReg(tmp, CSAR, 0U);
332
333 /* Reset DMAx_Channely destination address register */
334 LL_DMA_WriteReg(tmp, CDAR, 0U);
335
336 /* Check DMA channel */
337 if (IS_LL_DMA_2D_CHANNEL_INSTANCE(DMAx, Channel) != 0U)
338 {
339 /* Reset DMAx_Channely transfer register 3 */
340 LL_DMA_WriteReg(tmp, CTR3, 0U);
341
342 /* Reset DMAx_Channely Block register 2 */
343 LL_DMA_WriteReg(tmp, CBR2, 0U);
344 }
345
346 /* Reset DMAx_Channely Linked list address register */
347 LL_DMA_WriteReg(tmp, CLLR, 0U);
348
349 /* Reset DMAx_Channely pending flags */
350 LL_DMA_WriteReg(tmp, CFCR, 0x00003F00U);
351
352 /* Reset DMAx_Channely attribute */
353 LL_DMA_DisableChannelPrivilege(DMAx, Channel);
354
355 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
356 LL_DMA_DisableChannelSecure(DMAx, Channel);
357 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
358 }
359
360 return (uint32_t)status;
361 }
362
363 /**
364 * @brief Initialize the DMA registers according to the specified parameters
365 * in DMA_InitStruct.
366 * @note This API is used for all available DMA channels.
367 * @note A software request transfer can be done once programming the direction
368 * field in memory to memory value.
369 * @note To convert DMAx_Channely Instance to DMAx Instance and Channely, use
370 * helper macros :
371 * @arg @ref LL_DMA_GET_INSTANCE
372 * @arg @ref LL_DMA_GET_CHANNEL
373 * @param DMAx DMAx Instance
374 * @param Channel This parameter can be one of the following values:
375 * @arg @ref LL_DMA_CHANNEL_0
376 * @arg @ref LL_DMA_CHANNEL_1
377 * @arg @ref LL_DMA_CHANNEL_2
378 * @arg @ref LL_DMA_CHANNEL_3
379 * @arg @ref LL_DMA_CHANNEL_4
380 * @arg @ref LL_DMA_CHANNEL_5
381 * @arg @ref LL_DMA_CHANNEL_6
382 * @arg @ref LL_DMA_CHANNEL_7
383 * @param DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure.
384 * @retval An ErrorStatus enumeration value:
385 * - SUCCESS : DMA registers are initialized.
386 * - ERROR : Not applicable.
387 */
LL_DMA_Init(DMA_TypeDef * DMAx,uint32_t Channel,LL_DMA_InitTypeDef * DMA_InitStruct)388 uint32_t LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitTypeDef *DMA_InitStruct)
389 {
390 /* Check the DMA Instance DMAx and Channel parameters*/
391 assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel));
392
393 /* Check the DMA parameters from DMA_InitStruct */
394 assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction));
395
396 /* Check direction */
397 if (DMA_InitStruct->Direction != LL_DMA_DIRECTION_MEMORY_TO_MEMORY)
398 {
399 assert_param(IS_LL_DMA_REQUEST_SELECTION(DMA_InitStruct->Request));
400 }
401
402 assert_param(IS_LL_DMA_DATA_ALIGNMENT(DMA_InitStruct->DataAlignment));
403 assert_param(IS_LL_DMA_SRC_DATA_WIDTH(DMA_InitStruct->SrcDataWidth));
404 assert_param(IS_LL_DMA_DEST_DATA_WIDTH(DMA_InitStruct->DestDataWidth));
405 assert_param(IS_LL_DMA_SRC_INCREMENT_MODE(DMA_InitStruct->SrcIncMode));
406 assert_param(IS_LL_DMA_DEST_INCREMENT_MODE(DMA_InitStruct->DestIncMode));
407 assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority));
408 assert_param(IS_LL_DMA_BLK_DATALENGTH(DMA_InitStruct->BlkDataLength));
409 assert_param(IS_LL_DMA_TRIGGER_POLARITY(DMA_InitStruct->TriggerPolarity));
410 assert_param(IS_LL_DMA_BLKHW_REQUEST(DMA_InitStruct->BlkHWRequest));
411 assert_param(IS_LL_DMA_TRANSFER_EVENT_MODE(DMA_InitStruct->TransferEventMode));
412 assert_param(IS_LL_DMA_LINK_STEP_MODE(DMA_InitStruct->LinkStepMode));
413 assert_param(IS_LL_DMA_LINK_BASEADDR(DMA_InitStruct->LinkedListBaseAddr));
414 assert_param(IS_LL_DMA_LINK_ADDR_OFFSET(DMA_InitStruct->LinkedListAddrOffset));
415 assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode));
416 if (DMA_InitStruct->Mode == LL_DMA_PFCTRL)
417 {
418 assert_param(IS_LL_DMA_PFREQ_INSTANCE(DMAx, Channel));
419 }
420
421 /* Check DMA instance */
422 if (IS_LL_GPDMA_CHANNEL_INSTANCE(DMAx, Channel) != 0U)
423 {
424 assert_param(IS_LL_DMA_BURST_LENGTH(DMA_InitStruct->SrcBurstLength));
425 assert_param(IS_LL_DMA_BURST_LENGTH(DMA_InitStruct->DestBurstLength));
426 assert_param(IS_LL_DMA_DEST_HALFWORD_EXCHANGE(DMA_InitStruct->DestHWordExchange));
427 assert_param(IS_LL_DMA_DEST_BYTE_EXCHANGE(DMA_InitStruct->DestByteExchange));
428 assert_param(IS_LL_DMA_SRC_BYTE_EXCHANGE(DMA_InitStruct->SrcByteExchange));
429 assert_param(IS_LL_DMA_LINK_ALLOCATED_PORT(DMA_InitStruct->LinkAllocatedPort));
430 assert_param(IS_LL_DMA_SRC_ALLOCATED_PORT(DMA_InitStruct->SrcAllocatedPort));
431 assert_param(IS_LL_DMA_DEST_ALLOCATED_PORT(DMA_InitStruct->DestAllocatedPort));
432 }
433
434 /* Check trigger polarity */
435 if (DMA_InitStruct->TriggerPolarity != LL_DMA_TRIG_POLARITY_MASKED)
436 {
437 assert_param(IS_LL_DMA_TRIGGER_MODE(DMA_InitStruct->TriggerMode));
438 assert_param(IS_LL_DMA_TRIGGER_SELECTION(DMA_InitStruct->TriggerSelection));
439 }
440
441 /* Check DMA channel */
442 if (IS_LL_DMA_2D_CHANNEL_INSTANCE(DMAx, Channel) != 0U)
443 {
444 assert_param(IS_LL_DMA_BLK_REPEATCOUNT(DMA_InitStruct->BlkRptCount));
445 assert_param(IS_LL_DMA_BURST_SRC_ADDR_UPDATE(DMA_InitStruct->SrcAddrUpdateMode));
446 assert_param(IS_LL_DMA_BURST_DEST_ADDR_UPDATE(DMA_InitStruct->DestAddrUpdateMode));
447 assert_param(IS_LL_DMA_BURST_ADDR_UPDATE_VALUE(DMA_InitStruct->SrcAddrOffset));
448 assert_param(IS_LL_DMA_BURST_ADDR_UPDATE_VALUE(DMA_InitStruct->DestAddrOffset));
449 assert_param(IS_LL_DMA_BLKRPT_SRC_ADDR_UPDATE(DMA_InitStruct->BlkRptSrcAddrUpdateMode));
450 assert_param(IS_LL_DMA_BLKRPT_DEST_ADDR_UPDATE(DMA_InitStruct->BlkRptDestAddrUpdateMode));
451 assert_param(IS_LL_DMA_BLKRPT_ADDR_UPDATE_VALUE(DMA_InitStruct->BlkRptSrcAddrOffset));
452 assert_param(IS_LL_DMA_BLKRPT_ADDR_UPDATE_VALUE(DMA_InitStruct->BlkRptDestAddrOffset));
453 }
454
455 /*-------------------------- DMAx CLBAR Configuration ------------------------
456 * Configure the Transfer linked list address with parameter :
457 * - LinkedListBaseAdd: DMA_CLBAR_LBA[31:16] bits
458 */
459 LL_DMA_SetLinkedListBaseAddr(DMAx, Channel, DMA_InitStruct->LinkedListBaseAddr);
460
461 /*-------------------------- DMAx CCR Configuration --------------------------
462 * Configure the control parameter :
463 * - LinkAllocatedPort: DMA_CCR_LAP bit
464 * - LinkStepMode: DMA_CCR_LSM bit
465 * - Priority: DMA_CCR_PRIO [23:22] bits
466 */
467 LL_DMA_ConfigControl(DMAx, Channel, DMA_InitStruct->Priority | \
468 DMA_InitStruct->LinkAllocatedPort | \
469 DMA_InitStruct->LinkStepMode);
470
471 /*-------------------------- DMAx CTR1 Configuration -------------------------
472 * Configure the Data transfer parameter :
473 * - DestAllocatedPort: DMA_CTR1_DAP bit
474 * - DestHWordExchange: DMA_CTR1_DHX bit
475 * - DestByteExchange: DMA_CTR1_DBX bit
476 * - DestIncMode: DMA_CTR1_DINC bit
477 * - DestDataWidth: DMA_CTR1_DDW_LOG2 [17:16] bits
478 * - SrcAllocatedPort: DMA_CTR1_SAP bit
479 * - SrcByteExchange: DMA_CTR1_SBX bit
480 * - DataAlignment: DMA_CTR1_PAM [12:11] bits
481 * - SrcIncMode: DMA_CTR1_SINC bit
482 * - SrcDataWidth: DMA_CTR1_SDW_LOG2 [1:0] bits
483 * - SrcBurstLength: DMA_CTR1_SBL_1 [9:4] bits
484 * - DestBurstLength: DMA_CTR1_DBL_1 [25:20] bits
485 */
486 LL_DMA_ConfigTransfer(DMAx, Channel, DMA_InitStruct->DestAllocatedPort | \
487 DMA_InitStruct->DestHWordExchange | \
488 DMA_InitStruct->DestByteExchange | \
489 DMA_InitStruct->DestIncMode | \
490 DMA_InitStruct->DestDataWidth | \
491 DMA_InitStruct->SrcAllocatedPort | \
492 DMA_InitStruct->SrcByteExchange | \
493 DMA_InitStruct->DataAlignment | \
494 DMA_InitStruct->SrcIncMode | \
495 DMA_InitStruct->SrcDataWidth);
496 /* Check DMA instance */
497 if (IS_LL_GPDMA_CHANNEL_INSTANCE(DMAx, Channel) != 0U)
498 {
499 LL_DMA_ConfigBurstLength(DMAx, Channel, DMA_InitStruct->SrcBurstLength,
500 DMA_InitStruct->DestBurstLength);
501 }
502
503 /*-------------------------- DMAx CTR2 Configuration -------------------------
504 * Configure the channel transfer parameter :
505 * - TransferEventMode: DMA_CTR2_TCEM [31:30] bits
506 * - TriggerPolarity: DMA_CTR2_TRIGPOL [25:24] bits
507 * - TriggerMode: DMA_CTR2_TRIGM [15:14] bits
508 * - BlkHWRequest: DMA_CTR2_BREQ bit
509 * - Mode: DMA_CTR2_PFREQ bit
510 * - Direction: DMA_CTR2_DREQ bit
511 * - Direction: DMA_CTR2_SWREQ bit
512 * - TriggerSelection: DMA_CTR2_TRIGSEL [21:16] bits
513 * - Request: DMA_CTR2_REQSEL [6:0] bits
514 */
515 LL_DMA_ConfigChannelTransfer(DMAx, Channel, DMA_InitStruct->TransferEventMode | \
516 DMA_InitStruct->TriggerPolarity | \
517 DMA_InitStruct->BlkHWRequest | \
518 DMA_InitStruct->Mode | \
519 DMA_InitStruct->Direction);
520
521 /* Check direction */
522 if (DMA_InitStruct->Direction != LL_DMA_DIRECTION_MEMORY_TO_MEMORY)
523 {
524 LL_DMA_SetPeriphRequest(DMAx, Channel, DMA_InitStruct->Request);
525 }
526
527 /* Check trigger polarity */
528 if (DMA_InitStruct->TriggerPolarity != LL_DMA_TRIG_POLARITY_MASKED)
529 {
530 LL_DMA_SetHWTrigger(DMAx, Channel, DMA_InitStruct->TriggerSelection);
531 LL_DMA_SetTriggerMode(DMAx, Channel, DMA_InitStruct->TriggerMode);
532 }
533
534 /*-------------------------- DMAx CBR1 Configuration -------------------------
535 * Configure the Transfer Block counters and update mode with parameter :
536 * - BlkDataLength: DMA_CBR1_BNDT[15:0] bits
537 * - BlkRptCount: DMA_CBR1_BRC[26:16] bits
538 * BlkRptCount field is supported only by 2D addressing channels.
539 * - BlkRptSrcAddrUpdateMode: DMA_CBR1_BRSDEC bit
540 * BlkRptSrcAddrUpdateMode field is supported only by 2D addressing channels.
541 * - BlkRptDestAddrUpdateMode: DMA_CBR1_BRDDEC bit
542 * BlkRptDestAddrUpdateMode field is supported only by 2D addressing channels.
543 * - SrcAddrUpdateMode: DMA_CBR1_SDEC bit
544 * SrcAddrUpdateMode field is supported only by 2D addressing channels.
545 * - DestAddrUpdateMode: DMA_CBR1_DDEC bit
546 * DestAddrUpdateMode field is supported only by 2D addressing channels.
547 */
548 LL_DMA_SetBlkDataLength(DMAx, Channel, DMA_InitStruct->BlkDataLength);
549
550 /* Check DMA channel */
551 if (IS_LL_DMA_2D_CHANNEL_INSTANCE(DMAx, Channel) != 0U)
552 {
553 LL_DMA_SetBlkRptCount(DMAx, Channel, DMA_InitStruct->BlkRptCount);
554 LL_DMA_ConfigBlkRptAddrUpdate(DMAx, Channel, DMA_InitStruct->BlkRptSrcAddrUpdateMode | \
555 DMA_InitStruct->BlkRptDestAddrUpdateMode | \
556 DMA_InitStruct->SrcAddrUpdateMode | \
557 DMA_InitStruct->DestAddrUpdateMode);
558 }
559
560 /*-------------------------- DMAx CSAR and CDAR Configuration ----------------
561 * Configure the Transfer source address with parameter :
562 * - SrcAddress: DMA_CSAR_SA[31:0] bits
563 * - DestAddress: DMA_CDAR_DA[31:0] bits
564 */
565 LL_DMA_ConfigAddresses(DMAx, Channel, DMA_InitStruct->SrcAddress, DMA_InitStruct->DestAddress);
566
567 /* Check DMA channel */
568 if (IS_LL_DMA_2D_CHANNEL_INSTANCE(DMAx, Channel) != 0U)
569 {
570 /*------------------------ DMAx CTR3 Configuration -------------------------
571 * Configure the Transfer Block counters and update mode with parameter :
572 * - SrcAddrOffset: DMA_CTR3_SAO[28:16] bits
573 * SrcAddrOffset field is supported only by 2D addressing channels.
574 * - DestAddrOffset: DMA_CTR3_DAO[12:0] bits
575 * DestAddrOffset field is supported only by 2D addressing channels.
576 */
577 LL_DMA_ConfigAddrUpdateValue(DMAx, Channel, DMA_InitStruct->SrcAddrOffset, DMA_InitStruct->DestAddrOffset);
578
579 /*------------------------ DMAx CBR2 Configuration -----------------------
580 * Configure the Transfer Block counters and update mode with parameter :
581 * - BlkRptSrcAddrOffset: DMA_CBR2_BRSAO[15:0] bits
582 * BlkRptSrcAddrOffset field is supported only by 2D addressing channels.
583 * - BlkRptDestAddrOffset: DMA_CBR2_BRDAO[31:16] bits
584 * BlkRptDestAddrOffset field is supported only by 2D addressing channels.
585 */
586 LL_DMA_ConfigBlkRptAddrUpdateValue(DMAx, Channel, DMA_InitStruct->BlkRptSrcAddrOffset,
587 DMA_InitStruct->BlkRptDestAddrOffset);
588 }
589
590 /*-------------------------- DMAx CLLR Configuration -------------------------
591 * Configure the Transfer linked list address with parameter :
592 * - DestAddrOffset: DMA_CLLR_LA[15:2] bits
593 */
594 LL_DMA_SetLinkedListAddrOffset(DMAx, Channel, DMA_InitStruct->LinkedListAddrOffset);
595
596 return (uint32_t)SUCCESS;
597 }
598
599 /**
600 * @brief Set each @ref LL_DMA_InitTypeDef field to default value.
601 * @param DMA_InitStruct Pointer to a @ref LL_DMA_InitTypeDef structure.
602 * @retval None.
603 */
LL_DMA_StructInit(LL_DMA_InitTypeDef * DMA_InitStruct)604 void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct)
605 {
606 /* Set DMA_InitStruct fields to default values */
607 DMA_InitStruct->SrcAddress = 0x00000000U;
608 DMA_InitStruct->DestAddress = 0x00000000U;
609 DMA_InitStruct->Direction = LL_DMA_DIRECTION_MEMORY_TO_MEMORY;
610 DMA_InitStruct->BlkHWRequest = LL_DMA_HWREQUEST_SINGLEBURST;
611 DMA_InitStruct->DataAlignment = LL_DMA_DATA_ALIGN_ZEROPADD;
612 DMA_InitStruct->SrcBurstLength = 1U;
613 DMA_InitStruct->DestBurstLength = 1U;
614 DMA_InitStruct->SrcDataWidth = LL_DMA_SRC_DATAWIDTH_BYTE;
615 DMA_InitStruct->DestDataWidth = LL_DMA_DEST_DATAWIDTH_BYTE;
616 DMA_InitStruct->SrcIncMode = LL_DMA_SRC_FIXED;
617 DMA_InitStruct->DestIncMode = LL_DMA_DEST_FIXED;
618 DMA_InitStruct->Priority = LL_DMA_LOW_PRIORITY_LOW_WEIGHT;
619 DMA_InitStruct->BlkDataLength = 0x00000000U;
620 DMA_InitStruct->Mode = LL_DMA_NORMAL;
621 DMA_InitStruct->BlkRptCount = 0x00000000U;
622 DMA_InitStruct->TriggerMode = LL_DMA_TRIGM_BLK_TRANSFER;
623 DMA_InitStruct->TriggerPolarity = LL_DMA_TRIG_POLARITY_MASKED;
624 DMA_InitStruct->TriggerSelection = 0x00000000U;
625 DMA_InitStruct->Request = 0x00000000U;
626 DMA_InitStruct->TransferEventMode = LL_DMA_TCEM_BLK_TRANSFER;
627 DMA_InitStruct->DestHWordExchange = LL_DMA_DEST_HALFWORD_PRESERVE;
628 DMA_InitStruct->DestByteExchange = LL_DMA_DEST_BYTE_PRESERVE;
629 DMA_InitStruct->SrcByteExchange = LL_DMA_SRC_BYTE_PRESERVE;
630 DMA_InitStruct->SrcAllocatedPort = LL_DMA_SRC_ALLOCATED_PORT0;
631 DMA_InitStruct->DestAllocatedPort = LL_DMA_DEST_ALLOCATED_PORT0;
632 DMA_InitStruct->LinkAllocatedPort = LL_DMA_LINK_ALLOCATED_PORT0;
633 DMA_InitStruct->LinkStepMode = LL_DMA_LSM_FULL_EXECUTION;
634 DMA_InitStruct->SrcAddrUpdateMode = LL_DMA_BURST_SRC_ADDR_INCREMENT;
635 DMA_InitStruct->DestAddrUpdateMode = LL_DMA_BURST_DEST_ADDR_INCREMENT;
636 DMA_InitStruct->SrcAddrOffset = 0x00000000U;
637 DMA_InitStruct->DestAddrOffset = 0x00000000U;
638 DMA_InitStruct->BlkRptSrcAddrUpdateMode = LL_DMA_BLKRPT_SRC_ADDR_INCREMENT;
639 DMA_InitStruct->BlkRptDestAddrUpdateMode = LL_DMA_BLKRPT_DEST_ADDR_INCREMENT;
640 DMA_InitStruct->BlkRptSrcAddrOffset = 0x00000000U;
641 DMA_InitStruct->BlkRptDestAddrOffset = 0x00000000U;
642 DMA_InitStruct->LinkedListBaseAddr = 0x00000000U;
643 DMA_InitStruct->LinkedListAddrOffset = 0x00000000U;
644 }
645
646 /**
647 * @brief Set each @ref LL_DMA_InitLinkedListTypeDef field to default value.
648 * @param DMA_InitLinkedListStruct Pointer to
649 * a @ref LL_DMA_InitLinkedListTypeDef structure.
650 * @retval None.
651 */
LL_DMA_ListStructInit(LL_DMA_InitLinkedListTypeDef * DMA_InitLinkedListStruct)652 void LL_DMA_ListStructInit(LL_DMA_InitLinkedListTypeDef *DMA_InitLinkedListStruct)
653 {
654 /* Set LL_DMA_InitLinkedListTypeDef fields to default values */
655 DMA_InitLinkedListStruct->Priority = LL_DMA_LOW_PRIORITY_LOW_WEIGHT;
656 DMA_InitLinkedListStruct->LinkStepMode = LL_DMA_LSM_FULL_EXECUTION;
657 DMA_InitLinkedListStruct->TransferEventMode = LL_DMA_TCEM_LAST_LLITEM_TRANSFER;
658 DMA_InitLinkedListStruct->LinkAllocatedPort = LL_DMA_LINK_ALLOCATED_PORT0;
659 }
660
661 /**
662 * @brief De-initialize the DMA linked list.
663 * @note This API is used for all available DMA channels.
664 * @note To convert DMAx_Channely Instance to DMAx Instance and Channely, use
665 * helper macros :
666 * @arg @ref LL_DMA_GET_INSTANCE
667 * @arg @ref LL_DMA_GET_CHANNEL
668 * @param DMAx DMAx Instance
669 * @param Channel This parameter can be one of the following values:
670 * @arg @ref LL_DMA_CHANNEL_0
671 * @arg @ref LL_DMA_CHANNEL_1
672 * @arg @ref LL_DMA_CHANNEL_2
673 * @arg @ref LL_DMA_CHANNEL_3
674 * @arg @ref LL_DMA_CHANNEL_4
675 * @arg @ref LL_DMA_CHANNEL_5
676 * @arg @ref LL_DMA_CHANNEL_6
677 * @arg @ref LL_DMA_CHANNEL_7
678 * @retval An ErrorStatus enumeration value:
679 * - SUCCESS : DMA registers are de-initialized.
680 * - ERROR : DMA registers are not de-initialized.
681 */
LL_DMA_List_DeInit(DMA_TypeDef * DMAx,uint32_t Channel)682 uint32_t LL_DMA_List_DeInit(DMA_TypeDef *DMAx, uint32_t Channel)
683 {
684 return LL_DMA_DeInit(DMAx, Channel);
685 }
686
687 /**
688 * @brief Initialize the DMA linked list according to the specified parameters
689 * in LL_DMA_InitLinkedListTypeDef.
690 * @note This API is used for all available DMA channels.
691 * @note To convert DMAx_Channely Instance to DMAx Instance and Channely, use
692 * helper macros :
693 * @arg @ref LL_DMA_GET_INSTANCE
694 * @arg @ref LL_DMA_GET_CHANNEL
695 * @param DMAx DMAx Instance
696 * @param Channel This parameter can be one of the following values:
697 * @arg @ref LL_DMA_CHANNEL_0
698 * @arg @ref LL_DMA_CHANNEL_1
699 * @arg @ref LL_DMA_CHANNEL_2
700 * @arg @ref LL_DMA_CHANNEL_3
701 * @arg @ref LL_DMA_CHANNEL_4
702 * @arg @ref LL_DMA_CHANNEL_5
703 * @arg @ref LL_DMA_CHANNEL_6
704 * @arg @ref LL_DMA_CHANNEL_7
705 * @param DMA_InitLinkedListStruct pointer to
706 * a @ref LL_DMA_InitLinkedListTypeDef structure.
707 * @retval An ErrorStatus enumeration value:
708 * - SUCCESS : DMA registers are initialized.
709 * - ERROR : Not applicable.
710 */
LL_DMA_List_Init(DMA_TypeDef * DMAx,uint32_t Channel,LL_DMA_InitLinkedListTypeDef * DMA_InitLinkedListStruct)711 uint32_t LL_DMA_List_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitLinkedListTypeDef *DMA_InitLinkedListStruct)
712 {
713 /* Check the DMA Instance DMAx and Channel parameters*/
714 assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel));
715
716 /* Check the DMA parameters from DMA_InitLinkedListStruct */
717 assert_param(IS_LL_DMA_PRIORITY(DMA_InitLinkedListStruct->Priority));
718 assert_param(IS_LL_DMA_LINK_STEP_MODE(DMA_InitLinkedListStruct->LinkStepMode));
719 assert_param(IS_LL_DMA_TRANSFER_EVENT_MODE(DMA_InitLinkedListStruct->TransferEventMode));
720 /* Check DMA instance */
721 if (IS_LL_GPDMA_CHANNEL_INSTANCE(DMAx, Channel) != 0U)
722 {
723 assert_param(IS_LL_DMA_LINK_ALLOCATED_PORT(DMA_InitLinkedListStruct->LinkAllocatedPort));
724 }
725
726 /*-------------------------- DMAx CCR Configuration --------------------------
727 * Configure the control parameter :
728 * - LinkAllocatedPort: DMA_CCR_LAP bit
729 * LinkAllocatedPort field is supported only by GPDMA channels.
730 * - LinkStepMode: DMA_CCR_LSM bit
731 * - Priority: DMA_CCR_PRIO [23:22] bits
732 */
733 LL_DMA_ConfigControl(DMAx, Channel, DMA_InitLinkedListStruct->Priority | \
734 DMA_InitLinkedListStruct->LinkAllocatedPort | \
735 DMA_InitLinkedListStruct->LinkStepMode);
736
737 /*-------------------------- DMAx CTR2 Configuration -------------------------
738 * Configure the channel transfer parameter :
739 * - TransferEventMode: DMA_CTR2_TCEM [31:30] bits
740 */
741 LL_DMA_SetTransferEventMode(DMAx, Channel, DMA_InitLinkedListStruct->TransferEventMode);
742
743 return (uint32_t)SUCCESS;
744 }
745
746 /**
747 * @brief Set each @ref LL_DMA_InitNodeTypeDef field to default value.
748 * @param DMA_InitNodeStruct Pointer to a @ref LL_DMA_InitNodeTypeDef
749 * structure.
750 * @retval None.
751 */
LL_DMA_NodeStructInit(LL_DMA_InitNodeTypeDef * DMA_InitNodeStruct)752 void LL_DMA_NodeStructInit(LL_DMA_InitNodeTypeDef *DMA_InitNodeStruct)
753 {
754 /* Set DMA_InitNodeStruct fields to default values */
755 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
756 DMA_InitNodeStruct->DestSecure = LL_DMA_CHANNEL_DEST_NSEC;
757 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
758 DMA_InitNodeStruct->DestAllocatedPort = LL_DMA_DEST_ALLOCATED_PORT0;
759 DMA_InitNodeStruct->DestHWordExchange = LL_DMA_DEST_HALFWORD_PRESERVE;
760 DMA_InitNodeStruct->DestByteExchange = LL_DMA_DEST_BYTE_PRESERVE;
761 DMA_InitNodeStruct->DestBurstLength = 1U;
762 DMA_InitNodeStruct->DestIncMode = LL_DMA_DEST_FIXED;
763 DMA_InitNodeStruct->DestDataWidth = LL_DMA_DEST_DATAWIDTH_BYTE;
764 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
765 DMA_InitNodeStruct->SrcSecure = LL_DMA_CHANNEL_SRC_NSEC;
766 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
767 DMA_InitNodeStruct->SrcAllocatedPort = LL_DMA_SRC_ALLOCATED_PORT0;
768 DMA_InitNodeStruct->SrcByteExchange = LL_DMA_SRC_BYTE_PRESERVE;
769 DMA_InitNodeStruct->DataAlignment = LL_DMA_DATA_ALIGN_ZEROPADD;
770 DMA_InitNodeStruct->SrcBurstLength = 1U;
771 DMA_InitNodeStruct->SrcIncMode = LL_DMA_SRC_FIXED;
772 DMA_InitNodeStruct->SrcDataWidth = LL_DMA_SRC_DATAWIDTH_BYTE;
773 DMA_InitNodeStruct->TransferEventMode = LL_DMA_TCEM_BLK_TRANSFER;
774 DMA_InitNodeStruct->TriggerPolarity = LL_DMA_TRIG_POLARITY_MASKED;
775 DMA_InitNodeStruct->TriggerSelection = 0x00000000U;
776 DMA_InitNodeStruct->TriggerMode = LL_DMA_TRIGM_BLK_TRANSFER;
777 DMA_InitNodeStruct->BlkHWRequest = LL_DMA_HWREQUEST_SINGLEBURST;
778 DMA_InitNodeStruct->Direction = LL_DMA_DIRECTION_MEMORY_TO_MEMORY;
779 DMA_InitNodeStruct->Request = 0x00000000U;
780 DMA_InitNodeStruct->Mode = LL_DMA_NORMAL;
781 DMA_InitNodeStruct->BlkRptDestAddrUpdateMode = LL_DMA_BLKRPT_DEST_ADDR_INCREMENT;
782 DMA_InitNodeStruct->BlkRptSrcAddrUpdateMode = LL_DMA_BLKRPT_SRC_ADDR_INCREMENT;
783 DMA_InitNodeStruct->DestAddrUpdateMode = LL_DMA_BURST_DEST_ADDR_INCREMENT;
784 DMA_InitNodeStruct->SrcAddrUpdateMode = LL_DMA_BURST_SRC_ADDR_INCREMENT;
785 DMA_InitNodeStruct->BlkRptCount = 0x00000000U;
786 DMA_InitNodeStruct->BlkDataLength = 0x00000000U;
787 DMA_InitNodeStruct->SrcAddress = 0x00000000U;
788 DMA_InitNodeStruct->DestAddress = 0x00000000U;
789 DMA_InitNodeStruct->DestAddrOffset = 0x00000000U;
790 DMA_InitNodeStruct->SrcAddrOffset = 0x00000000U;
791 DMA_InitNodeStruct->BlkRptDestAddrOffset = 0x00000000U;
792 DMA_InitNodeStruct->BlkRptSrcAddrOffset = 0x00000000U;
793 DMA_InitNodeStruct->UpdateRegisters = (LL_DMA_UPDATE_CTR1 | LL_DMA_UPDATE_CTR2 | \
794 LL_DMA_UPDATE_CBR1 | LL_DMA_UPDATE_CSAR | \
795 LL_DMA_UPDATE_CDAR | LL_DMA_UPDATE_CTR3 | \
796 LL_DMA_UPDATE_CBR2 | LL_DMA_UPDATE_CLLR);
797 DMA_InitNodeStruct->NodeType = LL_DMA_GPDMA_LINEAR_NODE;
798 }
799
800 /**
801 * @brief Initializes DMA linked list node according to the specified
802 * parameters in the DMA_InitNodeStruct.
803 * @param DMA_InitNodeStruct Pointer to a LL_DMA_InitNodeTypeDef structure
804 * that contains linked list node
805 * registers configurations.
806 * @param pNode Pointer to linked list node to fill according to
807 * LL_DMA_LinkNodeTypeDef parameters.
808 * @retval None
809 */
LL_DMA_CreateLinkNode(LL_DMA_InitNodeTypeDef * DMA_InitNodeStruct,LL_DMA_LinkNodeTypeDef * pNode)810 uint32_t LL_DMA_CreateLinkNode(LL_DMA_InitNodeTypeDef *DMA_InitNodeStruct, LL_DMA_LinkNodeTypeDef *pNode)
811 {
812 uint32_t reg_counter = 0U;
813
814 /* Check the DMA Node type */
815 assert_param(IS_LL_DMA_LINK_NODETYPE(DMA_InitNodeStruct->NodeType));
816
817 /* Check the DMA parameters from DMA_InitNodeStruct */
818 assert_param(IS_LL_DMA_DIRECTION(DMA_InitNodeStruct->Direction));
819
820 /* Check direction */
821 if (DMA_InitNodeStruct->Direction != LL_DMA_DIRECTION_MEMORY_TO_MEMORY)
822 {
823 assert_param(IS_LL_DMA_REQUEST_SELECTION(DMA_InitNodeStruct->Request));
824 }
825
826 assert_param(IS_LL_DMA_DATA_ALIGNMENT(DMA_InitNodeStruct->DataAlignment));
827 assert_param(IS_LL_DMA_SRC_DATA_WIDTH(DMA_InitNodeStruct->SrcDataWidth));
828 assert_param(IS_LL_DMA_DEST_DATA_WIDTH(DMA_InitNodeStruct->DestDataWidth));
829 assert_param(IS_LL_DMA_SRC_INCREMENT_MODE(DMA_InitNodeStruct->SrcIncMode));
830 assert_param(IS_LL_DMA_DEST_INCREMENT_MODE(DMA_InitNodeStruct->DestIncMode));
831 assert_param(IS_LL_DMA_BLK_DATALENGTH(DMA_InitNodeStruct->BlkDataLength));
832 assert_param(IS_LL_DMA_TRIGGER_POLARITY(DMA_InitNodeStruct->TriggerPolarity));
833 assert_param(IS_LL_DMA_BLKHW_REQUEST(DMA_InitNodeStruct->BlkHWRequest));
834 assert_param(IS_LL_DMA_TRANSFER_EVENT_MODE(DMA_InitNodeStruct->TransferEventMode));
835 assert_param(IS_LL_DMA_LINK_UPDATE_REGISTERS(DMA_InitNodeStruct->UpdateRegisters));
836 assert_param(IS_LL_DMA_MODE(DMA_InitNodeStruct->Mode));
837
838 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
839 assert_param(IS_LL_DMA_CHANNEL_SRC_SEC(DMA_InitNodeStruct->SrcSecure));
840 assert_param(IS_LL_DMA_CHANNEL_DEST_SEC(DMA_InitNodeStruct->DestSecure));
841 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
842
843 /* Check trigger polarity */
844 if (DMA_InitNodeStruct->TriggerPolarity != LL_DMA_TRIG_POLARITY_MASKED)
845 {
846 assert_param(IS_LL_DMA_TRIGGER_MODE(DMA_InitNodeStruct->TriggerMode));
847 assert_param(IS_LL_DMA_TRIGGER_SELECTION(DMA_InitNodeStruct->TriggerSelection));
848 }
849
850 /* Check non 2D addressing settings */
851 {
852 assert_param(IS_LL_DMA_BURST_LENGTH(DMA_InitNodeStruct->SrcBurstLength));
853 assert_param(IS_LL_DMA_BURST_LENGTH(DMA_InitNodeStruct->DestBurstLength));
854 assert_param(IS_LL_DMA_DEST_HALFWORD_EXCHANGE(DMA_InitNodeStruct->DestHWordExchange));
855 assert_param(IS_LL_DMA_DEST_BYTE_EXCHANGE(DMA_InitNodeStruct->DestByteExchange));
856 assert_param(IS_LL_DMA_SRC_BYTE_EXCHANGE(DMA_InitNodeStruct->SrcByteExchange));
857 assert_param(IS_LL_DMA_SRC_ALLOCATED_PORT(DMA_InitNodeStruct->SrcAllocatedPort));
858 assert_param(IS_LL_DMA_DEST_ALLOCATED_PORT(DMA_InitNodeStruct->DestAllocatedPort));
859 }
860
861 /* Check DMA channel */
862 if (DMA_InitNodeStruct->NodeType == LL_DMA_GPDMA_2D_NODE)
863 {
864 assert_param(IS_LL_DMA_BLK_REPEATCOUNT(DMA_InitNodeStruct->BlkRptCount));
865 assert_param(IS_LL_DMA_BURST_SRC_ADDR_UPDATE(DMA_InitNodeStruct->SrcAddrUpdateMode));
866 assert_param(IS_LL_DMA_BURST_DEST_ADDR_UPDATE(DMA_InitNodeStruct->DestAddrUpdateMode));
867 assert_param(IS_LL_DMA_BURST_ADDR_UPDATE_VALUE(DMA_InitNodeStruct->SrcAddrOffset));
868 assert_param(IS_LL_DMA_BURST_ADDR_UPDATE_VALUE(DMA_InitNodeStruct->DestAddrOffset));
869 assert_param(IS_LL_DMA_BLKRPT_SRC_ADDR_UPDATE(DMA_InitNodeStruct->BlkRptSrcAddrUpdateMode));
870 assert_param(IS_LL_DMA_BLKRPT_DEST_ADDR_UPDATE(DMA_InitNodeStruct->BlkRptDestAddrUpdateMode));
871 assert_param(IS_LL_DMA_BLKRPT_ADDR_UPDATE_VALUE(DMA_InitNodeStruct->BlkRptSrcAddrOffset));
872 assert_param(IS_LL_DMA_BLKRPT_ADDR_UPDATE_VALUE(DMA_InitNodeStruct->BlkRptDestAddrOffset));
873 }
874
875 /* Check if CTR1 register update is enabled */
876 if ((DMA_InitNodeStruct->UpdateRegisters & LL_DMA_UPDATE_CTR1) == LL_DMA_UPDATE_CTR1)
877 {
878 /*-------------------------- DMAx CTR1 Configuration -----------------------
879 * Configure the Data transfer parameter :
880 * - DestAllocatedPort: DMA_CTR1_DAP bit
881 * - DestHWordExchange: DMA_CTR1_DHX bit
882 * - DestByteExchange: DMA_CTR1_DBX bit
883 * - DestIncMode: DMA_CTR1_DINC bit
884 * - DestDataWidth: DMA_CTR1_DDW_LOG2 [17:16] bits
885 * - SrcAllocatedPort: DMA_CTR1_SAP bit
886 * - SrcByteExchange: DMA_CTR1_SBX bit
887 * - DataAlignment: DMA_CTR1_PAM [12:11] bits
888 * - SrcIncMode: DMA_CTR1_SINC bit
889 * - SrcDataWidth: DMA_CTR1_SDW_LOG2 [1:0] bits
890 * - SrcBurstLength: DMA_CTR1_SBL_1 [9:4] bits
891 * - DestBurstLength: DMA_CTR1_DBL_1 [25:20] bits
892 */
893
894 pNode->LinkRegisters[reg_counter] = (DMA_InitNodeStruct->DestIncMode | \
895 DMA_InitNodeStruct->DestDataWidth | \
896 DMA_InitNodeStruct->DataAlignment | \
897 DMA_InitNodeStruct->SrcIncMode | \
898 DMA_InitNodeStruct->SrcDataWidth);
899
900 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
901 pNode->LinkRegisters[reg_counter] |= (DMA_InitNodeStruct->DestSecure | \
902 DMA_InitNodeStruct->SrcSecure);
903 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
904
905 /* Update CTR1 register fields */
906 pNode->LinkRegisters[reg_counter] |= (DMA_InitNodeStruct->DestAllocatedPort | \
907 DMA_InitNodeStruct->DestHWordExchange | \
908 DMA_InitNodeStruct->DestByteExchange | \
909 ((DMA_InitNodeStruct->DestBurstLength - 1U) << DMA_CTR1_DBL_1_Pos) | \
910 DMA_InitNodeStruct->SrcAllocatedPort | \
911 DMA_InitNodeStruct->SrcByteExchange | \
912 ((DMA_InitNodeStruct->SrcBurstLength - 1U) << DMA_CTR1_SBL_1_Pos));
913
914 /* Increment counter for the next register */
915 reg_counter++;
916 }
917
918
919 /* Check if CTR2 register update is enabled */
920 if ((DMA_InitNodeStruct->UpdateRegisters & LL_DMA_UPDATE_CTR2) == LL_DMA_UPDATE_CTR2)
921 {
922 /*-------------------------- DMAx CTR2 Configuration -----------------------
923 * Configure the channel transfer parameter :
924 * - TransferEventMode: DMA_CTR2_TCEM [31:30] bits
925 * - TriggerPolarity: DMA_CTR2_TRIGPOL [25:24] bits
926 * - TriggerMode: DMA_CTR2_TRIGM [15:14] bits
927 * - Mode: DMA_CTR2_PFREQ bit
928 * - BlkHWRequest: DMA_CTR2_BREQ bit
929 * - Direction: DMA_CTR2_DREQ bit
930 * - Direction: DMA_CTR2_SWREQ bit
931 * - TriggerSelection: DMA_CTR2_TRIGSEL [21:16] bits
932 * - Request: DMA_CTR2_REQSEL [6:0] bits
933 */
934 pNode->LinkRegisters[reg_counter] = (DMA_InitNodeStruct->TransferEventMode | \
935 DMA_InitNodeStruct->TriggerPolarity | \
936 DMA_InitNodeStruct->BlkHWRequest | \
937 DMA_InitNodeStruct->Mode | \
938 DMA_InitNodeStruct->Direction);
939
940 /* Check direction */
941 if (DMA_InitNodeStruct->Direction != LL_DMA_DIRECTION_MEMORY_TO_MEMORY)
942 {
943 pNode->LinkRegisters[reg_counter] |= DMA_InitNodeStruct->Request & DMA_CTR2_REQSEL;
944 }
945
946 /* Check trigger polarity */
947 if (DMA_InitNodeStruct->TriggerPolarity != LL_DMA_TRIG_POLARITY_MASKED)
948 {
949 pNode->LinkRegisters[reg_counter] |= (((DMA_InitNodeStruct->TriggerSelection << DMA_CTR2_TRIGSEL_Pos) & \
950 DMA_CTR2_TRIGSEL) | DMA_InitNodeStruct->TriggerMode);
951 }
952
953
954 /* Increment counter for the next register */
955 reg_counter++;
956 }
957
958 /* Check if CBR1 register update is enabled */
959 if ((DMA_InitNodeStruct->UpdateRegisters & LL_DMA_UPDATE_CBR1) == LL_DMA_UPDATE_CBR1)
960 {
961 /*-------------------------- DMAx CBR1 Configuration -----------------------
962 * Configure the Transfer Block counters and update mode with parameter :
963 * - BlkDataLength: DMA_CBR1_BNDT[15:0] bits
964 * - BlkRptCount: DMA_CBR1_BRC[26:16] bits
965 * BlkRptCount field is supported only by 2D addressing channels.
966 * - BlkRptSrcAddrUpdateMode: DMA_CBR1_BRSDEC bit
967 * BlkRptSrcAddrUpdateMode field is supported only by 2D addressing channels.
968 * - BlkRptDestAddrUpdateMode: DMA_CBR1_BRDDEC bit
969 * BlkRptDestAddrUpdateMode field is supported only by 2D addressing channels.
970 * - SrcAddrUpdateMode: DMA_CBR1_SDEC bit
971 * SrcAddrUpdateMode field is supported only by 2D addressing channels.
972 * - DestAddrUpdateMode: DMA_CBR1_DDEC bit
973 * DestAddrUpdateMode field is supported only by 2D addressing channels.
974 */
975 pNode->LinkRegisters[reg_counter] = DMA_InitNodeStruct->BlkDataLength;
976
977 /* Update CBR1 register fields for 2D addressing channels */
978 if (DMA_InitNodeStruct->NodeType == LL_DMA_GPDMA_2D_NODE)
979 {
980 pNode->LinkRegisters[reg_counter] |= (DMA_InitNodeStruct->BlkRptDestAddrUpdateMode | \
981 DMA_InitNodeStruct->BlkRptSrcAddrUpdateMode | \
982 DMA_InitNodeStruct->DestAddrUpdateMode | \
983 DMA_InitNodeStruct->SrcAddrUpdateMode | \
984 ((DMA_InitNodeStruct->BlkRptCount << DMA_CBR1_BRC_Pos) & DMA_CBR1_BRC));
985 }
986
987 /* Increment counter for the next register */
988 reg_counter++;
989 }
990
991 /* Check if CSAR register update is enabled */
992 if ((DMA_InitNodeStruct->UpdateRegisters & LL_DMA_UPDATE_CSAR) == LL_DMA_UPDATE_CSAR)
993 {
994 /*-------------------------- DMAx CSAR Configuration -----------------------
995 * Configure the Transfer Block counters and update mode with parameter :
996 * - SrcAddress: DMA_CSAR_SA[31:0] bits
997 */
998 pNode->LinkRegisters[reg_counter] = DMA_InitNodeStruct->SrcAddress;
999
1000 /* Increment counter for the next register */
1001 reg_counter++;
1002 }
1003
1004
1005 /* Check if CDAR register update is enabled */
1006 if ((DMA_InitNodeStruct->UpdateRegisters & LL_DMA_UPDATE_CDAR) == LL_DMA_UPDATE_CDAR)
1007 {
1008 /*-------------------------- DMAx CDAR Configuration -----------------------
1009 * Configure the Transfer Block counters and update mode with parameter :
1010 * - DestAddress: DMA_CDAR_DA[31:0] bits
1011 */
1012 pNode->LinkRegisters[reg_counter] = DMA_InitNodeStruct->DestAddress;
1013
1014 /* Increment counter for the next register */
1015 reg_counter++;
1016 }
1017
1018
1019 /* Update CTR3 register fields for 2D addressing channels */
1020 if (DMA_InitNodeStruct->NodeType == LL_DMA_GPDMA_2D_NODE)
1021 {
1022 /* Check if CTR3 register update is enabled */
1023 if ((DMA_InitNodeStruct->UpdateRegisters & LL_DMA_UPDATE_CTR3) == LL_DMA_UPDATE_CTR3)
1024 {
1025 /*-------------------------- DMAx CTR3 Configuration ---------------------
1026 * Configure the Block counters and update mode with parameter :
1027 * - DestAddressOffset: DMA_CTR3_DAO[12:0] bits
1028 * DestAddressOffset field is supported only by 2D addressing channels.
1029 * - SrcAddressOffset: DMA_CTR3_SAO[12:0] bits
1030 * SrcAddressOffset field is supported only by 2D addressing channels.
1031 */
1032 pNode->LinkRegisters[reg_counter] = (DMA_InitNodeStruct->SrcAddrOffset | \
1033 ((DMA_InitNodeStruct->DestAddrOffset << DMA_CTR3_DAO_Pos) & DMA_CTR3_DAO));
1034
1035 /* Increment counter for the next register */
1036 reg_counter++;
1037 }
1038 }
1039
1040
1041 /* Update CBR2 register fields for 2D addressing channels */
1042 if (DMA_InitNodeStruct->NodeType == LL_DMA_GPDMA_2D_NODE)
1043 {
1044 /* Check if CBR2 register update is enabled */
1045 if ((DMA_InitNodeStruct->UpdateRegisters & LL_DMA_UPDATE_CBR2) == LL_DMA_UPDATE_CBR2)
1046 {
1047 /*-------------------------- DMAx CBR2 Configuration ---------------------
1048 * Configure the Block counters and update mode with parameter :
1049 * - BlkRptDestAddrOffset: DMA_CBR2_BRDAO[31:16] bits
1050 * BlkRptDestAddrOffset field is supported only by 2D addressing channels.
1051 * - BlkRptSrcAddrOffset: DMA_CBR2_BRSAO[15:0] bits
1052 * BlkRptSrcAddrOffset field is supported only by 2D addressing channels.
1053 */
1054 pNode->LinkRegisters[reg_counter] = (DMA_InitNodeStruct->BlkRptSrcAddrOffset | \
1055 ((DMA_InitNodeStruct->BlkRptDestAddrOffset << DMA_CBR2_BRDAO_Pos) & \
1056 DMA_CBR2_BRDAO));
1057
1058 /* Increment counter for the next register */
1059 reg_counter++;
1060 }
1061 }
1062
1063 /* Check if CLLR register update is enabled */
1064 if ((DMA_InitNodeStruct->UpdateRegisters & LL_DMA_UPDATE_CLLR) == LL_DMA_UPDATE_CLLR)
1065 {
1066 /*-------------------------- DMAx CLLR Configuration -----------------------
1067 * Configure the Transfer Block counters and update mode with parameter :
1068 * - UpdateRegisters DMA_CLLR_UT1 bit
1069 * - UpdateRegisters DMA_CLLR_UT2 bit
1070 * - UpdateRegisters DMA_CLLR_UB1 bit
1071 * - UpdateRegisters DMA_CLLR_USA bit
1072 * - UpdateRegisters DMA_CLLR_UDA bit
1073 * - UpdateRegisters DMA_CLLR_UT3 bit
1074 * DMA_CLLR_UT3 bit is discarded for linear addressing channels.
1075 * - UpdateRegisters DMA_CLLR_UB2 bit
1076 * DMA_CLLR_UB2 bit is discarded for linear addressing channels.
1077 * - UpdateRegisters DMA_CLLR_ULL bit
1078 */
1079 pNode->LinkRegisters[reg_counter] = ((DMA_InitNodeStruct->UpdateRegisters & (DMA_CLLR_UT1 | DMA_CLLR_UT2 | \
1080 DMA_CLLR_UB1 | DMA_CLLR_USA | \
1081 DMA_CLLR_UDA | DMA_CLLR_ULL)));
1082
1083 /* Update CLLR register fields for 2D addressing channels */
1084 if (DMA_InitNodeStruct->NodeType == LL_DMA_GPDMA_2D_NODE)
1085 {
1086 pNode->LinkRegisters[reg_counter] |= (DMA_InitNodeStruct->UpdateRegisters & (DMA_CLLR_UT3 | DMA_CLLR_UB2));
1087 }
1088 }
1089 else
1090 {
1091 /* Reset of the CLLR of the node being created */
1092 pNode->LinkRegisters[reg_counter] = 0U;
1093 }
1094 return (uint32_t)SUCCESS;
1095 }
1096
1097 /**
1098 * @brief Connect Linked list Nodes.
1099 * @param pPrevLinkNode Pointer to previous linked list node to be connected to new Linked list node.
1100 * @param PrevNodeCLLRIdx Offset of Previous Node CLLR register.
1101 * This parameter can be a value of @ref DMA_LL_EC_CLLR_OFFSET.
1102 * @param pNewLinkNode Pointer to new Linked list.
1103 * @param NewNodeCLLRIdx Offset of New Node CLLR register.
1104 * This parameter can be a value of @ref DMA_LL_EC_CLLR_OFFSET.
1105 * @retval None
1106 */
LL_DMA_ConnectLinkNode(LL_DMA_LinkNodeTypeDef * pPrevLinkNode,uint32_t PrevNodeCLLRIdx,LL_DMA_LinkNodeTypeDef * pNewLinkNode,uint32_t NewNodeCLLRIdx)1107 void LL_DMA_ConnectLinkNode(LL_DMA_LinkNodeTypeDef *pPrevLinkNode, uint32_t PrevNodeCLLRIdx,
1108 LL_DMA_LinkNodeTypeDef *pNewLinkNode, uint32_t NewNodeCLLRIdx)
1109 {
1110 pPrevLinkNode->LinkRegisters[PrevNodeCLLRIdx] = (((uint32_t)pNewLinkNode & DMA_CLLR_LA) | \
1111 (pNewLinkNode->LinkRegisters[NewNodeCLLRIdx] & (DMA_CLLR_UT1 | \
1112 DMA_CLLR_UT2 | DMA_CLLR_UB1 | DMA_CLLR_USA | DMA_CLLR_UDA | \
1113 DMA_CLLR_UT3 | DMA_CLLR_UB2 | DMA_CLLR_ULL)));
1114 }
1115
1116 /**
1117 * @brief Disconnect the next linked list node.
1118 * @param pLinkNode Pointer to linked list node to be disconnected from the next one.
1119 * @param LinkNodeCLLRIdx Offset of Link Node CLLR register.
1120 * @retval None.
1121 */
LL_DMA_DisconnectNextLinkNode(LL_DMA_LinkNodeTypeDef * pLinkNode,uint32_t LinkNodeCLLRIdx)1122 void LL_DMA_DisconnectNextLinkNode(LL_DMA_LinkNodeTypeDef *pLinkNode, uint32_t LinkNodeCLLRIdx)
1123 {
1124 pLinkNode->LinkRegisters[LinkNodeCLLRIdx] = 0;
1125 }
1126
1127 /**
1128 * @}
1129 */
1130
1131 /**
1132 * @}
1133 */
1134
1135 /**
1136 * @}
1137 */
1138
1139 #endif /* GPDMA1 */
1140
1141 /**
1142 * @}
1143 */
1144
1145 #endif /* USE_FULL_LL_DRIVER */
1146