fgdma.md 7.8 KB
Newer Older
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:

-