• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  *
15  * Description: Provides DMA driver api \n
16  *
17  * History: \n
18  * 2022-10-16, Create file. \n
19  */
20 
21 #ifndef DMA_H
22 #define DMA_H
23 
24 #include <stdint.h>
25 #include "errcode.h"
26 
27 #ifdef __cplusplus
28 #if __cplusplus
29 extern "C" {
30 #endif /* __cplusplus */
31 #endif /* __cplusplus */
32 
33 /**
34  * @defgroup drivers_driver_dma DMA
35  * @ingroup  drivers_driver
36  * @{
37  */
38 
39 /**
40  * @if Eng
41  * @brief  Memory-to-memory type of DMA channel user configuration.
42  * @else
43  * @brief  内存到内存类型的DMA通道用户配置。
44  * @endif
45  */
46 typedef struct dma_ch_user_memory_config {
47     /** @if Eng  The source address of this transfer.
48      *  @else    传输源地址。
49      *  @endif */
50     uint32_t src;
51     /** @if Eng  The destination address of this transfer.
52      *  @else    传输目的地址。
53      *  @endif */
54     uint32_t dest;
55     /** @if Eng  Transfer number.
56      *  @else    传输数据量。
57      *  @endif */
58     uint16_t transfer_num;
59     /** @if Eng  Transfer priority of channel(Lowest: 0 and Highest: 3).
60      *  @else    传输通道优先级(最低为0以及最高为3)。
61      *  @endif */
62     uint8_t priority;
63     /** @if Eng  Transfer data width:
64      *           - 0: 1byte
65      *           - 1: 2byte
66      *           - 2: 4byte
67      *  @else    传输数据宽度:
68      *           - 0: 1字节
69      *           - 1: 2字节
70      *           - 2: 4字节
71      *  @endif */
72     uint8_t width;
73 } dma_ch_user_memory_config_t;
74 
75 /**
76  * @if Eng
77  * @brief  Memory-to-periph or periph-to-memory type of DMA channel user configuration.
78  * @else
79  * @brief  内存到外设或外设到内存类型的DMA通道用户配置。
80  * @endif
81  */
82 typedef struct dma_ch_user_peripheral_config {
83     /** @if Eng  The source address of this transfer.
84      *  @else    传输源地址。
85      *  @endif */
86     uint32_t src;
87     /** @if Eng  The destination address of this transfer.
88      *  @else    传输目的地址。
89      *  @endif */
90     uint32_t dest;
91     /** @if Eng  Transfer number.
92      *  @else    传输数据量。
93      *  @endif */
94     uint16_t transfer_num;
95     /** @if Eng  Hardware handshaking ID of the source. see @ref hal_dma_handshaking_source_t.
96      *  @else    源端硬件握手号。 参考 @ref hal_dma_handshaking_source_t 。
97      *  @endif */
98     uint16_t src_handshaking;
99     /** @if Eng  Hardware handshaking ID of the destination. see @ref hal_dma_handshaking_source_t.
100      *  @else    目的端硬件握手号。 参考 @ref hal_dma_handshaking_source_t 。
101      *  @endif */
102     uint16_t dest_handshaking;
103     /** @if Eng  Transfer type:
104      *           - 0: memory to memory and DMA is flow controller
105      *           - 1: memory to periph and DMA is flow controller
106      *           - 2: periph to memory and DMA is flow controller
107      *           - 3: periph to periph and DMA is flow controller
108      *           - 4: periph to memory and periph is flow controller
109      *           - 5: periph to periph and source periph is flow controller
110      *           - 6: memory to periph and periph is flow controller
111      *           - 7: periph to periph and destination periph is flow controller
112      *  @else    传输类型:
113      *           - 0: 内存到内存并且由DMA流控
114      *           - 1: 内存到外设并且由DMA流控
115      *           - 2: 外设到内存并且由DMA流控
116      *           - 3: 外设到外设并且由DMA流控
117      *           - 4: 外设到内存并且由外设流控
118      *           - 5: 外设到外设并且由源端外设流控
119      *           - 6: 内存到外设并且由外设流控
120      *           - 7: 外设到外设并且由目的端外设流控
121      *  @endif */
122     uint8_t trans_type;
123     /** @if Eng  Transfer direction:
124      *           - 0: memory to periph
125      *           - 1: periph to memory
126      *           - 2: periph to periph
127      *  @else    传输方向:
128      *           - 0: 内存到外设
129      *           - 1: 外设到内存
130      *           - 2: 外设到外设
131      *  @endif */
132     uint8_t trans_dir;
133     /** @if Eng  Transfer priority of channel(Lowest: 0 and Highest: 3).
134      *  @else    传输通道优先级(最低为0以及最高为3)。
135      *  @endif */
136     uint8_t priority;
137     /** @if Eng  Transfer data width of the source:
138      *           - 0: 1byte
139      *           - 1: 2byte
140      *           - 2: 4byte
141      *  @else    源端传输数据宽度:
142      *           - 0: 1字节
143      *           - 1: 2字节
144      *           - 2: 4字节
145      *  @endif */
146     uint8_t src_width;
147     /** @if Eng  Transfer data width of the destination:
148      *           - 0: 1byte
149      *           - 1: 2byte
150      *           - 2: 4byte
151      *  @else    目的端传输数据宽度:
152      *           - 0: 1字节
153      *           - 1: 2字节
154      *           - 2: 4字节
155      *  @endif */
156     uint8_t dest_width;
157     /** @if Eng  Transfer burst length:
158      *           - 0: burst length is 1
159      *           - 1: burst length is 4
160      *           - 2: burst length is 8
161      *           - 3: burst length is 16
162      *  @else    传输burst长度:
163      *           - 0: burst长度是1
164      *           - 1: burst长度是4
165      *           - 2: burst长度是8
166      *           - 3: burst长度是16
167      *  @endif */
168     uint8_t burst_length;
169     /** @if Eng  Source address incremental mode:
170      *           - 0: increment
171      *           - 1: decrement
172      *           - 2: no change
173      *  @else    源端地址增量模式:
174      *           - 0: 递增
175      *           - 1: 递减
176      *           - 2: 不变
177      *  @endif */
178     uint8_t src_increment;
179     /** @if Eng  Destination address incremental mode:
180      *           - 0: increment
181      *           - 1: decrement
182      *           - 2: no change
183      *  @else    目的端地址增量模式:
184      *           - 0: 递增
185      *           - 1: 递减
186      *           - 2: 不变
187      *  @endif */
188     uint8_t dest_increment;
189     /** @if Eng  DMA protection control bits used to drive the AHB HPROT[3:1] bus:
190      *           - 0: HPROT[1]
191      *           - 1: HPROT[2]
192      *           - 2: HPROT[3]
193      *  @else    保护控制位,用于驱动AHB HPRO[3:1]总线:
194      *           - 0: HPROT[1]
195      *           - 1: HPROT[2]
196      *           - 2: HPROT[3]
197      *  @endif */
198     uint8_t protection;
199 } dma_ch_user_peripheral_config_t;
200 
201 /**
202  * @if Eng
203  * @brief  Pointer to the DMA channel transfer done/error callback function.
204  * @param  [in]  intr DMA interrupt type.
205  * @param  [in]  channel DMA channel.
206  * @param  [in]  arg DMA private param pointer passed by DMA caller.
207  * @else
208  * @brief  DMA通道传输完成/错误所触发的回调函数指针。
209  * @param  [in]  intr DMA中断类型。
210  * @param  [in]  channel DMA通道。
211  * @param  [in]  arg 调用DMA传输时传递的私有参数指针。
212  * @endif
213  */
214 typedef void (*dma_transfer_cb_t)(uint8_t intr, uint8_t channel, uintptr_t arg);
215 
216 /**
217  * @if Eng
218  * @brief  Initialize the DMA module.
219  * @retval ERRCODE_SUCC Success.
220  * @retval Other        Failure. For details, see @ref errcode_t.
221  * @else
222  * @brief  初始化DMA模块。
223  * @retval ERRCODE_SUCC 成功。
224  * @retval Other        失败 参考 @ref errcode_t 。
225  * @endif
226  */
227 errcode_t uapi_dma_init(void);
228 
229 /**
230  * @if Eng
231  * @brief  Deinitialize the DMA module.
232  * @else
233  * @brief  去初始化DMA模块。
234  * @endif
235  */
236 void uapi_dma_deinit(void);
237 
238 /**
239  * @if Eng
240  * @brief  Open the DMA module.
241  * @retval ERRCODE_SUCC Success.
242  * @retval Other        Failure. For details, see @ref errcode_t.
243  * @else
244  * @brief  开启DMA模块。
245  * @retval ERRCODE_SUCC 成功。
246  * @retval Other        失败 参考 @ref errcode_t 。
247  * @endif
248  */
249 errcode_t uapi_dma_open(void);
250 
251 /**
252  * @if Eng
253  * @brief  Close the DMA module.
254  * @else
255  * @brief  关闭DMA模块。
256  * @endif
257  */
258 void uapi_dma_close(void);
259 
260 /**
261  * @if Eng
262  * @brief  Start DMA transfer of specific Channel.
263  * @param  [in]  channel DMA channel.
264  * @retval ERRCODE_SUCC Success.
265  * @retval Other        Failure. For details, see @ref errcode_t.
266  * @else
267  * @brief  启动指定通道的DMA传输。
268  * @param  [in]  channel DMA通道。
269  * @retval ERRCODE_SUCC 成功。
270  * @retval Other        失败 参考 @ref errcode_t 。
271  * @endif
272  */
273 errcode_t uapi_dma_start_transfer(uint8_t channel);
274 
275 /**
276  * @if Eng
277  * @brief  Stop DMA transfer of specific Channel.
278  * @param  [in]  channel DMA channel.
279  * @retval ERRCODE_SUCC Success.
280  * @retval Other        Failure. For details, see @ref errcode_t.
281  * @else
282  * @brief  停止指定通道的DMA传输。
283  * @param  [in]  channel DMA通道。
284  * @retval ERRCODE_SUCC 成功。
285  * @retval Other        失败 参考 @ref errcode_t 。
286  * @endif
287  */
288 errcode_t uapi_dma_end_transfer(uint8_t channel);
289 
290 /**
291  * @if Eng
292  * @brief  Get the number of data transferred by the DMA.
293  * @param  [in]  channel DMA channel.
294  * @retval The number of data transferred by the DMA.
295  * @else
296  * @brief  获取DMA传输的数据量。
297  * @param  [in]  channel DMA通道。
298  * @retval 获取DMA传输的数据量。
299  * @endif
300  */
301 uint32_t uapi_dma_get_block_ts(uint8_t channel);
302 
303 /**
304  * @if Eng
305  * @brief  Transfer type memory-to-memory through DMA channel.
306  * @param  [in]  user_cfg DMA channel transfer configuration of user. For details, see @ref dma_ch_user_memory_config_t.
307  * @param  [in]  callback Channel transfer done/error callback function. For details, see @ref dma_transfer_cb_t.
308  * @param  [in]  arg Private param pointer for storing self information, which can be passed to DMA callback
309  *                     @ref dma_transfer_cb_t when transfer completed.
310  * @retval ERRCODE_SUCC Success.
311  * @retval Other        Failure. For details, see @ref errcode_t.
312  * @else
313  * @brief  通过DMA通道传输类型为内存到内存的数据。
314  * @param  [in]  user_cfg 用户的DMA通道传输配置 For details, see @ref dma_ch_user_memory_config_t 。
315  * @param  [in]  callback 通道传输完成/错误回调函数 For details, see @ref dma_transfer_cb_t 。
316  * @param  [in]  arg 用于存储自定义信息的私有参数指针,传输完成时回传给dma回调函数 @ref dma_transfer_cb_t 。
317  * @retval ERRCODE_SUCC 成功。
318  * @retval Other        失败 参考 @ref errcode_t 。
319  * @endif
320  */
321 errcode_t uapi_dma_transfer_memory_single(const dma_ch_user_memory_config_t *user_cfg,
322                                           dma_transfer_cb_t callback, uintptr_t arg);
323 
324 /**
325  * @if Eng
326  * @brief  Transfer type memory-periph or periph-memory through DMA channel.
327  * @param  [in]  user_cfg DMA channel transfer configuration of user.
328  *                      For details, see @ref dma_ch_user_peripheral_config_t.
329  * @param  [out] channel DMA channel selected.
330  * @param  [in]  callback Channel transfer done/error callback function. For details, see @ref dma_transfer_cb_t.
331  * @param  [in]  arg Private param pointer for storing self information, which can be passed to DMA callback
332  *                     @ref dma_transfer_cb_t when transfer completed.
333  * @retval ERRCODE_SUCC Success.
334  * @retval Other        Failure. For details, see @ref errcode_t.
335  * @else
336  * @brief  通过DMA通道传输类型为内存到外设或外设到内存的数据。
337  * @param  [in]  user_cfg 用户的DMA通道传输配置 For details, see @ref dma_ch_user_peripheral_config_t 。
338  * @param  [out] channel 获取被选择的通道。
339  * @param  [in]  callback 通道传输完成/错误回调函数 For details, see @ref dma_transfer_cb_t 。
340  * @param  [in]  arg 用于存储自定义信息的私有参数指针,传输完成时回传给DMA回调函数 @ref dma_transfer_cb_t 。
341  * @retval ERRCODE_SUCC 成功。
342  * @retval Other        失败 参考 @ref errcode_t 。
343  * @endif
344  */
345 errcode_t uapi_dma_configure_peripheral_transfer_single(const dma_ch_user_peripheral_config_t *user_cfg,
346                                                         uint8_t *channel, dma_transfer_cb_t callback, uintptr_t arg);
347 
348 #if defined(CONFIG_DMA_SUPPORT_LLI)
349 /**
350  * @if Eng
351  * @brief  Get DMA linked list channel.
352  * @param  [in]  burst_length Dma burst transfer length.
353  * @param  [in]  handshaking Dma Transfer periph.
354  * @retval ERRCODE_SUCC Success.
355  * @retval The DMA channel.
356  * @else
357  * @brief  获取DMA链表传输通道。
358  * @param  [in]  burst_length DMA的burst传输长度。
359  * @param  [in]  handshaking DMA传输外设种类。
360  * @retval DMA通道
361  * @endif
362  */
363 uint8_t uapi_dma_get_lli_channel(uint8_t burst_length, uint8_t handshaking);
364 
365 /**
366  * @if Eng
367  * @brief  Transfer type memory-to-memory in linked list mode through DMA channel.
368  * @param  [in]  channel DMA channel.
369  * @param  [in]  user_cfg DMA channel transfer configuration of user. For details, see @ref dma_ch_user_memory_config_t.
370  * @param  [in]  callback Channel transfer done/error callback function. For details, see @ref dma_transfer_cb_t.
371  * @retval ERRCODE_SUCC Success.
372  * @retval Other        Failure. For details, see @ref errcode_t.
373  * @else
374  * @brief  通过DMA通道以链表模式传输类型为内存到内存的数据。
375  * @param  [in]  channel DMA通道。
376  * @param  [in]  user_cfg 用户的DMA通道传输配置 For details, see @ref dma_ch_user_memory_config_t 。
377  * @param  [in]  callback 通道传输完成/错误回调函数 For details, see @ref dma_transfer_cb_t 。
378  * @retval ERRCODE_SUCC 成功。
379  * @retval Other        失败 参考 @ref errcode_t 。
380  * @endif
381  */
382 errcode_t uapi_dma_transfer_memory_lli(uint8_t channel, const dma_ch_user_memory_config_t *user_cfg,
383                                        dma_transfer_cb_t callback);
384 
385 /**
386  * @if Eng
387  * @brief  Transfer type memory-periph or periph-memory in linked list mode through DMA channel.
388  * @param  [in]  channel DMA channel.
389  * @param  [in]  user_cfg DMA channel transfer configuration of user.
390  *                      For details, see @ref dma_ch_user_peripheral_config_t.
391  * @param  [in]  callback Channel transfer done/error callback function. For details, see @ref dma_transfer_cb_t.
392  * @retval ERRCODE_SUCC Success.
393  * @retval Other        Failure. For details, see @ref errcode_t.
394  * @else
395  * @brief  通过DMA通道以链表模式传输类型为内存到外设或外设到内存的数据。
396  * @param  [in]  channel DMA通道。
397  * @param  [in]  user_cfg 用户的DMA通道传输配置 For details, see @ref dma_ch_user_peripheral_config_t 。
398  * @param  [in]  callback 通道传输完成/错误回调函数 For details, see @ref dma_transfer_cb_t 。
399  * @retval ERRCODE_SUCC 成功。
400  * @retval Other        失败 参考 @ref errcode_t 。
401  * @endif
402  */
403 errcode_t uapi_dma_configure_peripheral_transfer_lli(uint8_t channel, const dma_ch_user_peripheral_config_t *user_cfg,
404                                                      dma_transfer_cb_t callback);
405 
406 /**
407  * @if Eng
408  * @brief  Enable DMA linked list transfer.
409  * @param  [in]  channel DMA channel.
410  * @param  [in]  callback Channel transfer done/error callback function. For details, see @ref dma_transfer_cb_t.
411  * @param  [in]  arg Private param pointer for storing self information, which can be passed to DMA callback
412  *                     @ref dma_transfer_cb_t when transfer completed.
413  * @retval ERRCODE_SUCC Success.
414  * @retval Other        Failure. For details, see @ref errcode_t.
415  * @else
416  * @brief  启用DMA链表传输。
417  * @param  [in]  channel DMA通道。
418  * @param  [in]  callback 通道传输完成/错误回调函数 For details, see @ref dma_transfer_cb_t 。
419  * @param  [in]  arg 用于存储自定义信息的私有参数指针,传输完成时回传给dma回调函数 @ref dma_transfer_cb_t 。
420  * @retval ERRCODE_SUCC 成功。
421  * @retval Other        失败 参考 @ref errcode_t 。
422  * @endif
423  */
424 errcode_t uapi_dma_enable_lli(uint8_t channel, dma_transfer_cb_t callback, uintptr_t arg);
425 #endif /* CONFIG_DMA_SUPPORT_LLI */
426 
427 #ifdef CONFIG_DMA_SUPPORT_LPM
428 /**
429  * @if Eng
430  * @brief  Resume the DMA module.
431  * @param  [in]  arg Argument for resume.
432  * @retval ERRCODE_SUCC Success.
433  * @retval Other        Failure. For details, see @ref errcode_t.
434  * @else
435  * @brief  恢复DMA模块。
436  * @retval ERRCODE_SUCC 成功。
437  * @retval Other        失败 参考 @ref errcode_t
438  * @endif
439  */
440 errcode_t uapi_dma_resume(uintptr_t arg);
441 
442 /**
443  * @if Eng
444  * @brief  suspend the DMA module.
445  * @param  [in]  arg Argument for suspend.
446  * @retval ERRCODE_SUCC Success.
447  * @retval Other        Failure. For details, see @ref errcode_t
448  * @else
449  * @brief  挂起DMA模块。
450  * @retval ERRCODE_SUCC 成功。
451  * @retval Other        失败,参考 @ref errcode_t 。
452  * @endif
453  */
454 errcode_t uapi_dma_suspend(uintptr_t arg);
455 #endif
456 /**
457  * @}
458  */
459 
460 #ifdef __cplusplus
461 #if __cplusplus
462 }
463 #endif /* __cplusplus */
464 #endif /* __cplusplus */
465 
466 #endif
467