APP DMA驱动
结构体
app_dma_params_t
结构体定义如下:
| 成员 | 描述 | 取值 |
|---|---|---|
| dma_regs_t *p_instance |
DMA实例 |
该参数的取值可以是下列值中的任意一个: GR5526/GR5x25:
GR551x/GR533x/GR5405:
|
| dma_channel_t channel_number |
DMA通道 |
该参数的取值可以是下列值中的任意一个: GR5526/GR5x25:
GR533x/GR5405:
GR551x:
说明: 不采用链式传输方式,每个通道一次最大搬运长度为4095拍。 |
| dma_init_t init |
DMA配置 |
参考dma_init_t结构体 |
详细信息请参考文件:SDK_Folder\drivers\inc\app_dma.h。
各Bluetooth LE芯片中DMA支持的外设如下表,外设在使用DMA传输方式时,需要根据下表选择支持的DMA实例。其中xx_M表示仅可作Master端,xx_S表示仅可作Slave端。
| 芯片 | DMA0 | DMA1 |
|---|---|---|
| GR551x | QSPI0_M | / |
| QSPI1_M | / | |
| SPI_M | / | |
| SPI_S | / | |
| UART0 | / | |
| UART1 | / | |
| I2C0 | / | |
| I2C1 | / | |
| I2S_M | / | |
| I2S_S | / | |
| ADC | / | |
| GR5526 |
QSPI0_M | QSPI1_M |
| QSPI1_M | QSPI2_M | |
| OSPI_M | OSPI_M | |
| SPI_M | SPI_M | |
| SPI_S | DSPI_M | |
| UART0 | UART0 | |
| UART1 | UART3 | |
| UART2 | UART4 | |
| UART3 | UART5 | |
| UART4 | I2S_M | |
| I2C2 | I2S_S | |
| I2C3 | PDM | |
| I2C4 | I2C0 | |
| I2C5 | I2C1 | |
| ADC | / | |
| GR5x25 | QSPI0_M | QSPI1_M |
| QSPI1_M | QSPI2_M | |
| SPI_M | SPI_M | |
| SPI_S | DSPI_M | |
| UART0 | UART0 | |
| UART1 | UART3 | |
| UART2 | I2S_M | |
| UART3 | I2S_S | |
| I2C2 | PDM | |
| I2C3 | I2C0 | |
| ADC | I2C1 | |
| GR533x/GR5405 | SPI_M | / |
| SPI_S | / | |
| UART0 | / | |
| UART1 | / | |
| I2C0 | / | |
| I2C1 | / | |
| ADC | / | |
| PWM0 | / |
dma_init_t
结构体定义如下:
| 成员 | 描述 | 取值 |
|---|---|---|
| uint32_t src_request |
源端硬件请求信号 |
0x0 ~ 0xF(默认0x0) |
| uint32_t dst_request |
目的端硬件请求信号 |
0x0 ~ 0xF(默认0x0) |
| uint32_t direction |
数据传输方向 |
该参数的取值可以是下列值中的任意一个:
|
| uint32_t src_increment |
源地址更新方式 |
该参数的取值可以是下列值中的任意一个:
|
| uint32_t dst_increment |
目的地址更新方式 |
该参数的取值可以是下列值中的任意一个:
|
| uint32_t src_data_alignment |
源数据传输位宽 |
该参数的取值可以是下列值中的任意一个:
|
| uint32_t dst_data_alignment |
目的数据传输位宽 |
该参数的取值可以是下列值中的任意一个:
|
| uint32_t mode |
传输模式 |
该参数的取值可以是下列值中的任意一个:
|
| uint32_t priority |
优先级 |
该参数的取值可以是下列值中的任意一个:
|
- GR551x/GR5526/GR5x25:SDK_Folder\drivers\inc\hal\gr55xx_hal_dma.h
- GR533x:SDK_Folder\drivers\inc\hal\gr533x_hal_dma.h
- GR5405:SDK_Folder\hal_drv\include\hal_dma.h
dma_sg_llp_config_t
结构体定义如下:
| 成员 | 描述 | 取值 |
|---|---|---|
| dma_scatter_config_t scatter_config |
分散传输配置 |
参考dma_scatter_config_t结构体 |
| dma_gather_config_t gather_config |
聚合传输配置 |
参考dma_gather_config_t结构体 |
| dma_llp_config_t llp_config |
传输链表配置 |
参考dma_llp_config_t结构体 |
详细信息请参考文件:SDK_Folder\drivers\inc\hal\gr55xx_hal_dma.h。
dma_scatter_config_t
结构体定义如下:
| 成员 | 描述 | 取值 |
|---|---|---|
| uint32_t dst_scatter_en |
目的端分散使能 |
该参数的取值可以是下列值中的任意一个:
|
| uint32_t dst_dsi |
目的端分散间隔 |
0x0 ~ 0xFFFFF |
| uint32_t dst_dsc |
目的端分散计数 |
0x0 ~ 0xFFF |
详细信息请参考文件:SDK_Folder\drivers\inc\hal\gr55xx_hal_dma.h。
dma_gather_config_t
结构体定义如下:
| 成员 | 描述 | 取值 |
|---|---|---|
| uint32_t src_gather_en |
源端聚合使能 |
该参数的取值可以是下列值中的任意一个:
|
| uint32_t src_sgi |
源端聚合间隔 |
0x0 ~ 0xFFFFF |
| uint32_t src_sgc |
源端聚合计数 |
0x0 ~ 0xFFF |
详细信息请参考文件:SDK_Folder\drivers\inc\hal\gr55xx_hal_dma.h。
dma_llp_config_t
结构体定义如下:
| 成员 | 描述 | 取值 |
|---|---|---|
| uint32_t llp_src_en |
源端传输链表使能 |
该参数的取值可以是下列值中的任意一个:
|
| uint32_t llp_src_writeback |
源端回写状态值 |
0x0 ~ 0xFFFFFFFF |
| uint32_t llp_dst_en |
目的端传输链表使能 |
该参数的取值可以是下列值中的任意一个:
|
| uint32_t llp_dst_writeback |
目的端回写状态值 |
0x0 ~ 0xFFFFFFFF |
| struct dma_block_config *head_lli |
传输链表头 |
参考dma_block_config结构体 |
详细信息请参考文件:SDK_Folder\drivers\inc\hal\gr55xx_hal_dma.h。
dma_block_config
结构体定义如下:
| 成员 | 描述 | 取值 |
|---|---|---|
| uint32_t src_address |
源端地址 |
0x0 ~ 0xFFFFFFFF |
| uint32_t dst_address |
目的端地址 |
0x0 ~ 0xFFFFFFFF |
| struct dma_block_config *p_lli |
传输链表下一个节点地址 |
0x0 ~ 0xFFFFFFFF |
| uint32_t CTL_L |
控制寄存器低32位配置 |
0x0 ~ 0xFFFFFFFF |
| uint32_t CTL_H |
控制寄存器高32位配置 |
0x0 ~ 0xFFFFFFFF |
| uint32_t src_status |
源端传输状态(回写) |
0x0 ~ 0xFFFFFFFF |
| uint32_t dst_status |
目的端传输状态(回写) |
0x0 ~ 0xFFFFFFFF |
详细信息请参考文件:SDK_Folder\drivers\inc\hal\gr55xx_hal_dma.h。
枚举
app_dma_evt_type_t
枚举定义如下:
| 成员 | 描述 |
|---|---|
| APP_DMA_EVT_ERROR = 0 |
DMA传输错误事件 |
| APP_DMA_EVT_TFR = 1 |
DMA传输完成事件 |
| APP_DMA_EVT_BLK = 2 |
DMA块传输完成事件 |
app_dma_state_t
枚举定义如下:
| 成员 | 描述 |
|---|---|
| APP_DMA_INVALID = 0 | DMA不可用 |
| APP_DMA_ACTIVITY = 1 | DMA激活 |
| APP_DMA_SLEEP = 2 | DMA睡眠 |
详细信息请参考文件:SDK_Folder\drivers\inc\app_dma.h。
接口函数
| API | 芯片 | ||||
|---|---|---|---|---|---|
| GR551x | GR5526 | GR5x25 | GR533x | GR5405 | |
| app_dma_init |
Y |
Y |
Y |
Y |
Y |
| app_dma_deinit |
Y |
Y |
Y |
Y |
Y |
| app_dma_start |
Y |
Y |
Y |
Y |
Y |
| app_dma_get_handle |
Y |
Y |
Y |
Y |
Y |
| dma_wake_up |
Y |
Y |
Y |
Y |
Y |
| app_dma_start_sg_llp |
N |
Y |
Y |
N |
N |
app_dma_init
| 函数原型 | dma_id_t app_dma_init(app_dma_params_t *p_params, app_dma_evt_handler_t evt_handler) |
|---|---|
| 功能说明 | 初始化DMA |
| 输入参数 |
|
| 返回值 | dma_id_t:DMA通道ID |
| 备注 | 回调函数形式参照typedef void (*app_dma_evt_handler_t)(app_dma_evt_type_t type); HAL层已经实现中断标志位的清理,用户不用关心中断标志的清理,回调函数根据返回事件类型进行相应的处理即可。 |
app_dma_deinit
| 函数原型 | uint16_t app_dma_deinit(dma_id_t id) |
|---|---|
| 功能说明 | 反初始化DMA |
| 输入参数 | id:DMA通道ID |
| 返回值 | APP_DRV_xxx:详见SDK_Folder\drivers\inc\app_drv_error.h宏定义 |
| 备注 |
app_dma_start
| 函数原型 | uint16_t app_dma_start(dma_id_t id, uint32_t src_address, uint32_t dst_address, uint32_t data_length) |
|---|---|
| 功能说明 | 开启DMA传输 |
| 输入参数 |
|
| 返回值 | APP_DRV_xxx:详见SDK_Folder\drivers\inc\app_drv_error.h宏定义 |
| 备注 |
app_dma_get_handle
| 函数原型 | dma_handle_t *app_dma_get_handle(dma_id_t id) |
|---|---|
| 功能说明 | 获取DMA句柄 |
| 输入参数 | id:DMA通道ID |
| 返回值 |
DMA句柄,详见:
|
| 备注 |
dma_wake_up
| 函数原型 | void dma_wake_up(dma_id_t id) |
|---|---|
| 功能说明 | 系统唤醒后,唤醒DMA模块 |
| 输入参数 | id:DMA通道ID |
| 返回值 | |
| 备注 |
app_dma_start_sg_llp
| 函数原型 | uint16_t app_dma_start_sg_llp(dma_id_t id, uint32_t src_address, uint32_t dst_address, uint32_t data_length, dma_sg_llp_config_t *sg_llp_config) |
|---|---|
| 功能说明 | 开启DMA传输,带有分散聚合与链表传输配置 |
| 输入参数 |
|
| 返回值 | APP_DRV_xxx:详见SDK_Folder\drivers\inc\app_drv_error.h宏定义 |
| 备注 |
示例工程
DMA Memory
示例工程实现DMA方式将数据从一块内存搬运到另一块内存,工程路径:SDK_Folder\projects\peripheral\dma\app_dma。
流程图
初始化参数
app_dma_params_t dma_params = {DMA0,DMA_Channel0, 0};
dma_params.p_instance = DMA0;
dma_params.channel_number = DMA_Channel0;
dma_params.init.direction = DMA_MEMORY_TO_MEMORY;
dma_params.init.src_increment = DMA_SRC_INCREMENT;
dma_params.init.dst_increment = DMA_DST_INCREMENT;
dma_params.init.src_data_alignment = DMA_SDATAALIGN_BYTE;
dma_params.init.dst_data_alignment = DMA_DDATAALIGN_BYTE;
dma_params.init.priority = DMA_PRIORITY_LOW;
s_dma_channel_id = app_dma_init(&dma_params, app_dma_callback);
- p_instance :DMA模块ID,选择DMA0。
- channel_number:DMA通道,选择DMA_Channel0,即通道0。
- init.direction:DMA传输方向,选择DMA_MEMORY_TO_MEMORY,即传输方向内存到内存。
- init.src_increment:源地址更新方式,选择DMA_SRC_INCREMENT,即源端地址递增。
- init.dst_increment:目的地址更新方式,选择DMA_DST_INCREMENT,即目的端地址递增。
- init.src_data_alignment:源数据宽度,选择DMA_SDATAALIGN_BYTE,即源数据宽度8 bits。
- init.dst_data_alignment:目标数据宽度,选择DMA_DDATAALIGN_BYTE,即目标数据宽度8 bits。
其他可选配置请参考结构体相关定义。
重要函数
-
DMA初始化
s_dma_channel_id = app_dma_init(&dma_params, app_dma_callback);-
dma_params:初始化参数结构体
-
app_dma_callback:用户自定义的回调函数
-
s_dma_channel_id:返回的DMA通道ID
-
-
DMA数据传输
app_dma_start(s_dma_channel_id, (uint32_t)&g_src_data, (uint32_t)&g_dst_data, DMA_DATA_LEN);-
g_src_data:源数据数组
-
g_dst_data:目的数据数组
-
DMA_DATA_LEN:传输数据的长度
-
测试验证
连接开发板到PC端,打开串口调试助手,连接串口。串口日志显示DMA搬运数据的对比结果,如下:
app_dma0_memory_to_memory: success
app_dma1_memory_to_memory: success
This example demo end.