DMA
函数列表
简要说明
- DMA(Direct Memory Access,直接内存存取)它允许不同速度的硬件装置之间沟通,而不需要依赖于CPU的大量中断负载。
接口描述
csi_dma_alloc_channel
int32_t csi_dma_alloc_channel(void)
功能描述:
- 申请dma通道号。
参数:
- 无
返回值:
>=0: 通道号。
其它: 错误码。
csi_dma_power_control
int32_t csi_dma_power_control(int32_t ch, csi_power_stat_e state)
功能描述:
- 配置设备实例的功耗模式。
参数:
ch
: 通道号。state
: 设备实例的功耗模式,参看 csi_power_stat_e的定义。
返回值:
- 错误码。
csi_dma_get_capabilities
dma_capabilities_t csi_dma_get_capabilities(int32_t ch)
功能描述:
- 获取dma通道实例支持的能力。
参数:
ch
: 通道号。
返回值:
- 描述dma能力的结构体,dma的能力定义见 dma_capabilities_t 。
dma_capabilities_t:
名字 | 定义 | 备注 |
---|---|---|
uint32_t unalign_addr : 1 | 支持不对齐地址传输模式(传输源是memory) |
csi_dma_release_channel
void csi_dma_release_channel(int32_t ch)
功能描述:
- 释放通道号ch。
参数:
ch
: 通道号。
返回值:
- 无。
csi_dma_config_channel
int32_t csi_dma_config_channel(int32_t ch, dma_config_t *config, dma_event_cb_t cb_event)
功能描述:
- 配置dma通道ch。
参数:
ch
: 通道号。config
: 具体配置项结构体。配置结构体原型定义见 dma_config_t 。cb_event
: dma 通道ch的事件回调函数(一般在中断上下文执行)。回调函数原型定义见dma_event_cb_t。回调函数类型dma_event_cb_t定义如下:
typedef void (*dma_event_cb_t)(int32_t ch, dma_event_e event);
其中ch为通道号,event 为传给回调函数的事件类型。
dma中ch回调事件枚举类型见 dma_event_e 定义。
返回值:
- 错误码。
dma_event_e:
名字 | 定义 | 备注 |
---|---|---|
DMA_EVENT_TRANSFER_DONE | 传输完成事件 | |
DMA_EVENT_TRANSFER_HALF_DONE | 传输一半完成事件 | |
DMA_EVENT_TRANSFER_MODE_DONE | 传输完成事件(触发模式) | |
DMA_EVENT_CHANNEL_PEND | 通道挂起事件 | |
DMA_EVENT_TRANSFER_ERROR | 传输错误事件 |
dma_config_t:
名字 | 定义 | 备注 |
---|---|---|
src_inc | 源地址变化方式,参看的定义 | |
dst_inc | 目的地址变化方式,参看dma_addr_inc_e的定义 | |
src_endian | 源地址大小端模式,参看dma_addr_endian_e的定义 | |
dst_endian | 目的地址大小端模式,参看dma_addr_endian_e的定义 | |
src_tw | 源传输数据宽度 | |
dst_tw | 目的传输数据宽度 | |
hs_if | 硬件握手(可选) | |
preemption | 某通道抢占配置 | |
type | 传输类型配置,参看dma_trans_type_e的定义 | |
mode | 触发模式配置,参看dma_trig_trans_mode_e的定义 | |
ch_mode | 通道申请使用模式配置,参看dma_channel_req_mode_e定义 | |
single_dir | 单次传输方向枚举类型dma_single_dir_e定义 | |
group_len | 组传输长度设置,当触发模式配置为GROUP_TRIGGER模式 |
dma_addr_inc_e:
名字 | 定义 | 备注 |
---|---|---|
DMA_ADDR_INC | 地址递增方式 | |
DMA_ADDR_DEC | 地址递减方式 | |
DMA_ADDR_CONSTANT | 地址不变方式 |
dma_trans_type_e:
名字 | 定义 | 备注 |
---|---|---|
DMA_MEM2MEM | 内存至内存传输类型 | |
DMA_MEM2PERH | 内存至外设传输类型 | |
DMA_PERH2MEM | 外设至内存传输类型 | |
DMA_PERH2PERH | 外设至外设传输类型 |
dma_trig_trans_mode_e:
名字 | 定义 | 备注 |
---|---|---|
DMA_SINGLE_TRIGGER | 单次触发模式 | |
DMA_GROUP_TRIGGER | 组触发模式 | |
DMA_BLOCK_TRIGGER | 块触发模式 |
dma_single_dir_e:
名字 | 定义 | 备注 |
---|---|---|
DMA_DIR_DEST | 目的方向 | |
DMA_DIR_SOURCE | 源方向 |
dma_addr_endian_e:
名字 | 定义 | 备注 |
---|---|---|
DMA_ADDR_LITTLE | 小端模式 | |
DMA_ADDR_BIG | 大端模式 |
dma_channel_req_mode_e:
名字 | 定义 | 备注 |
---|---|---|
DMA_MODE_HARDWARE | 硬件模式 | |
DMA_MODE_SOFTWARE | 软件模式 |
csi_dma_start
void csi_dma_start(int32_t ch, void *psrcaddr, void *pdstaddr, uint32_t length)
功能描述:
- dma传输开始。
参数:
ch
: 通道号。psrcaddr
: 通道ch进行dma传输的源地址。pdstaddr
: 通道ch进行dma传输的目的地址。length
: 通道ch进行dma传输的数据长度。
返回值:
- 无。
csi_dma_stop
void csi_dma_stop(int32_t ch)
功能描述:
- dma传输结束。
参数:
ch
: 通道号。
返回值:
- 无。
csi_dma_get_status
dma_status_e csi_dma_get_status(int32_t ch)
功能描述:
- 获取当前时刻ch通道号状态。
参数:
ch
: 通道号。
返回值:
- dma状态的枚举,dma的状态定义见 dma_status_e 。
dma_status_e:
名字 | 定义 | 备注 |
---|---|---|
DMA_EVENT_TRANSFER_DONE | 传输完成 | |
DMA_EVENT_TRANSFER_HALF_DONE | 传输完成一半 | |
DMA_EVENT_TRANSFER_MODE_DONE | 传输完成(某触发模式) | |
DMA_EVENT_CAHNNEL_PEND | 被抢占挂起状态 | |
DMA_EVENT_TRANSFER_ERROR | 传输异常 |
示例
DMA示例1
static volatile uint8_t dma_cb_flag = 0;
ifndef DMA_M2M_SIZE
define DMA_M2M_SIZE 512
endif
static uint8_t p_src[DMA_M2M_SIZE] = {0};
static uint8_t p_dst[DMA_M2M_SIZE] = {0};
static void sleep(uint32_t k)
{
int i, j;
for (i = 0; i < 1000; i++) {
for (j = 0; j < k; j++);
}
}
static void dma_event_cb_fun(int32_t ch, dma_event_e event)
{
dma_cb_flag = 1;
}
static int32_t dma_test_mem2mem(dmac_handle_t dma_handle, uint8_t ch)
{
uint32_t i;
dma_config_t config;
uint32_t ret;
for (i = 0; i < DMA_M2M_SIZE; i++) {
p_src[i] = i;
}
memset(p_dst, 0, DMA_M2M_SIZE);
ch = csi_dma_alloc_channel(dma_handle, ch);
if (ch < 0) {
printf("csi_dma_alloc_channel error\n");
return -1;
}
config.src_inc = DMA_ADDR_INC;
config.dst_inc = DMA_ADDR_INC;
config.src_endian = DMA_ADDR_LITTLE;
config.dst_endian = DMA_ADDR_LITTLE;
config.src_tw = 1;
config.dst_tw = 1;
config.group_len = 8;
config.mode = DMA_BLOCK_TRIGGER;
config.type = DMA_MEM2MEM;
config.ch_mode = DMA_MODE_SOFTWARE;
ret = csi_dma_config_channel(dma_handle, ch, &config, dma_event_cb_fun);
if (ret < 0) {
printf("csi_dma_config_channel error\n");
return 0;
}
ret = csi_dma_start(dma_handle, ch, p_src, p_dst, DMA_M2M_SIZE);
if (ret < 0) {
printf("csi_dma_start error\n");
return 0;
}
printf("sleep or do other things while data in transfermation using DMA\n");
sleep(1);
//while (csi_dma_get_status(dma_handle, ch) != DMA_STATE_DONE) ;
while (!dma_cb_flag);
for (i = 0; i < DMA_M2M_SIZE; i++) {
if (p_dst[i] != p_src[i]) {
return -1;
}
}
ret = csi_dma_stop(dma_handle, ch);
if (ret < 0) {
printf("csi_dma_stop error\n");
}
ret = csi_dma_release_channel(dma_handle, ch);
if (ret < 0) {
printf("csi_dma_release_channel error\n");
return 0;
}
ret = csi_dma_uninitialize(dma_handle);
if (ret < 0) {
printf("csi_dma_uninitialize error\n");
return 0;
}
printf("dma_mem2mem_test_func OK\n");
return 0;
}
void example_dmac(void)
{
int32_t ret;
dmac_handle_t dma_handle = NULL;
dma_handle = csi_dma_initialize(0);
if (dma_handle == NULL) {
printf("csi_dma_initialize error\n");
return ;
}
ret = dma_test_mem2mem(dma_handle, 0);
if (ret < 0) {
printf("test dma mem to mem error\n");
return ;
}
}