1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
|
# FGDMA 驱动程序
## 1. 概述
GDMA(Generic Direct Memory Access),提供多个DMA通道,多个通道可以同时工作,独立配置给不同内存数据搬运使用
## 2. 功能
FGDMA 驱动程序主要完成 GDMA 模块的初始化,GDMA 通道的分配与释放,
相关源文件为:
```
fgdma
.
├── fgdma.c
├── fgdma.h
├── fgdma_g.c
├── fgdma_hw.h
├── fgdma_intr.c
├── fgdma_selftest.c
└── fgdma_sinit.c
```
## 3. 配置方法
以下部分将指导您完成 FGDMA 驱动的软件配置:
- 初始化 GDMA 控制器
- 配置 GDMA 通道,使用直接模式或者 BDL 模式进行操作
- 启动 GDMA 通道
## 4. 应用示例
### [通过GDMA拷贝内存数据](../../../baremetal/example/peripheral/dma/fgdma_async_memcpy)
## 5. API参考
### 5.1. 用户数据结构
#### FGdmaConfig
- GDMA控制器配置
```c
typedef struct
{
u32 instance_id; /* GDMA控制器ID */
u32 irq_num; /* GDMA控制器中断号 */
u32 irq_prority; /* GDMA控制器中断优先级 */
volatile uintptr_t base_addr; /* GDMA控制器基地址 */
FGdmaOperPriority rd_qos; /* 读操作优先级 */
FGdmaOperPriority wr_qos; /* 写操作优先级 */
} FGdmaConfig;
```
#### FGdmaChanConfig
- DMA通道配置
```c
typedef struct
{
FGdmaChanIndex chan_id; /* DMA通道ID */
FGdmaOperPriority rd_qos; /* DMA通道读Qos配置 */
FGdmaOperPriority wr_qos; /* DMA通道写Qos配置 */
FGdmaOperMode trans_mode; /* DMA通道的操作模式,直接模式或者BDL模式 */
/* Direct模式有效 */
FGdmaBurstSize rd_align; /* DMA读请求的Burst对齐方式 */
FGdmaBurstSize wr_align; /* DMA写请求的Burst对齐方式 */
/* BDL模式有效 */
boolean roll_back; /* 循环模式,TRUE: 当前BDL列表完成后,从第一个BDL项从新开始传输 */
FGdmaBdlDesc *descs;
u32 total_desc_num;
u32 valid_desc_num;
} FGdmaChanConfig; /* DMA通道配置 */
```
#### FGdmaChan
- GDMA通道实例
```c
typedef struct _FGdmaChan
{
FGdmaChanConfig config; /* DMA通道配置 */
FGdma *gdma; /* DMA控制器实例 */
FGdmaChanEvtHandler evt_handlers[FGDMA_CHAN_NUM_OF_EVT]; /* DMA通道事件回调函数 */
void *evt_handler_args[FGDMA_CHAN_NUM_OF_EVT]; /* DMA通道事件回调函数入参 */
} FGdmaChan; /* GDMA通道实例 */
```
#### FGdma
- GDMA控制器实例
```c
typedef struct _FGdma
{
FGdmaConfig config; /* GDMA控制器配置 */
u32 is_ready; /* GDMA控制器初始化是否完成 */
FGdmaChan *chans[FGDMA_NUM_OF_CHAN]; /* GDMA通道实例,如果通道没有分配,值为NULL */
} FGdma; /* GDMA控制器实例 */
```
#### FGdmaBdlDesc
- BDL描述符
```c
typedef struct
{
u32 src_addr_l; /* 0x0, 数据源地址低32位 */
u32 src_addr_h; /* 0x4, 数据源地址高32位 */
u32 dst_addr_l; /* 0x8, 数据目的地址低32位 */
u32 dst_addr_h; /* 0xc, 数据目的地址高32位 */
#define FGDMA_SRC_TC_BDL_BURST_SET(x) SET_REG32_BITS((x), 1U, 0U)
#define FGDMA_SRC_TC_BDL_SIZE_SET(x) SET_REG32_BITS((x), 6U, 4U)
#define FGDMA_SRC_TC_BDL_LEN_SET(x) SET_REG32_BITS((x), 15U, 8U)
u32 src_tc; /* 0x10, 源传输控制位 */
#define FGDMA_DST_TC_BDL_BURST_SET(x) SET_REG32_BITS((x), 1U, 0U)
#define FGDMA_DST_TC_BDL_SIZE_SET(x) SET_REG32_BITS((x), 6U, 4U)
#define FGDMA_DST_TC_BDL_LEN_SET(x) SET_REG32_BITS((x), 15U, 8U)
u32 dst_tc; /* 0x14, 目的传输控制 */
u32 total_bytes;/* 0x18, 传输数据总量,以Byte为单位 */
u32 ioc; /* 0x1c, 该条目传输完成中断产生控制位 */
} __attribute__((__packed__)) FGdmaBdlDesc; /* BDL描述符 */
```
### 5.2 错误码定义
#define FGDMA_SUCCESS : 成功
#define FGDMA_ERR_NOT_INIT : 驱动未初始化
#define FGDMA_ERR_CHAN_IN_USE : 通道已经绑定无法分配
#define FGDMA_ERR_CHAN_NOT_INIT : 通道未初始化
#define FGDMA_ERR_INVALID_ADDR : 传输地址非法
#define FGDMA_ERR_INVALID_SIZE : 传输字节数非法
#define FGDMA_ERR_BDL_NOT_ENOUGH : BDL已经使用完
### 5.3. 用户API接口
#### FGdmaLookupConfig
```c
const FGdmaConfig *FGdmaLookupConfig(u32 instance_id)
```
Note:
- 获取GDMA控制器默认配置
Input:
- {u32} instance_id, GDMA控制器ID
Return:
- {const FGdmaConfig *} 控制器默认配置
#### FGdmaCfgInitialize
```c
FError FGdmaCfgInitialize(FGdma *const instance_p, const FGdmaConfig *input_config)
```
Note:
- 初始化GDMA控制器实例
Input:
- FGdma *const instance_p, GDMA控制器实例
- const FGdmaConfig *input_config, GDMA控制器配置
Return:
- {FError} 返回FGDMA_SUCCESS表示初始化成功,返回其它表示失败
#### FGdmaDeInitialize
```c
void FGdmaDeInitialize(FGdma *const instance_p)
```
Note:
- 去初始化GDMA控制器实例
Input:
- FGdma *const instance_p, GDMA控制器实例
Return:
- 无
#### FGdmaAllocateChan
```c
FError FGdmaAllocateChan(FGdma *const instance_p, FGdmaChan *const dma_chan,
const FGdmaChanConfig *dma_chan_config)
```
Note:
- 分配指定GDMA通道
Input:
- FGdma *const instance_p, GDMA控制器实例
- FGdmaChan *const dma_chan, GDMA通道实例
- const FGdmaChanConfig *dma_chan_config, GDMA通道配置
Return:
- {FError} FGDMA_SUCCESS表示分配成功,返回其它值表示分配失败
#### FGdmaDellocateChan
```c
FError FGdmaDellocateChan(FGdmaChan *const dma_chan)
```
Note:
- 释放GDMA通道
Input:
- FGdmaChan *const dma_chan, GDMA通道实例
Return:
- {FError} FGDMA_SUCCESS表示处理成功
#### FGdmaDirectTransfer
```c
FError FGdmaDirectTransfer(FGdmaChan *const chan_p, uintptr src_addr, uintptr dst_addr, fsize_t data_len);
```
Note:
- 直接操作模式下发起DMA传输
Input:
- FGdmaChan *const chan_p, GDMA通道实例
- uintptr src_addr, 传输源地址
- uintptr dst_addr, 传输目的地址
Return:
- {FError} FGDMA_SUCCESS表示传输成功
#### FGdmaAppendBDLEntry
```c
FError FGdmaAppendBDLEntry(FGdmaChan *const chan_p, uintptr src_addr, uintptr dst_addr, fsize_t data_len)
```
Note:
- 设置BDL描述符的一个条目
Input:
- FGdmaBdlDesc *desc_entry, 一条BDL描述符
- uintptr src_addr, 传输源地址
- uintptr dst_addr, 传输目的地址
- fsize_t data_len, 传输数据长度
Return:
- {FError} FGDMA_SUCCESS 表示设置成功
#### FGdmaBDLTransfer
```c
FError FGdmaBDLTransfer(FGdmaChan *const chan_p)
```
Note:
- BDL操作模式下发起DMA传输
Input:
- FGdmaChan *const chan_p, DMA通道实例
Return:
- {FError} FGDMA_SUCCESS 表示传输成功
#### FGdmaStart
```c
FError FGdmaStart(FGdma *const instance_p)
```
Note:
- 使能启动GDMA控制器
- 先调用此函数,后调用FGdmaAllocateChan配置特定通道
Input:
- FGdma *const instance_p, GDMA控制器实例
Return:
- {FError} FGDMA_SUCCESS表示启动成功
#### FGdmaStop
```c
FError FGdmaStop(FGdma *const instance_p)
```
Note:
- 停止GDMA控制器
Input:
- FGdma *const instance_p, GDMA控制器实例
Return:
- {FError} FGDMA_SUCCESS表示处理成功
#### FGdmaIrqHandler
```c
void FGdmaIrqHandler(s32 vector, void *args)
```
Note:
- GDMA中断处理函数
Input:
- {s32} vector, 中断号
- {void} *args, 中断参数
Return:
- 无
#### FGdmaChanRegisterEvtHandler
```c
void FGdmaChanRegisterEvtHandler(FGdmaChan *const chan_p, FGdmaChanEvtType evt,
FGdmaChanEvtHandler handler, void *handler_arg)
```
Note:
- 注册GDMA通道事件回调函数
Input:
- {FGdmaChan} *chan_p, GDMA通道实例
- {FGdmaChanEvtType} evt, 通道事件
- {FGdmaChanEvtHandler} handler, 事件回调函数
- {void} *handler_arg, 事件回调函数输入参数
Return:
- 无
|