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 ;
    }
}

results matching ""

    No results matching ""