DMA (AHBDMA总线控制器)

简介

AHB DMA 用于在外设与存储器之间以及存储器与存储器之间提供高速数据传输,可以 在无需任何 CPU 操作的情况下通过 DMA 快速移动数据。这样节省的 CPU 资源可供其它操 作使用。 AHB DMA 控制器总共 2 个,每个有 8 个逻辑通道,8 对硬件握手接口,每一个 DMA 控制器都用于管理一个或多个外设的存储器访问请求。

功能概述

  • 支持 4 种数据传输方向, - 内存到内存 (M2M) - 内存到外设 (M2P) - 外设到内存 (P2M) - 外设到外设 (P2P)

  • 支持 3 种数据传输宽度,如 8bit,16bit, 32bit

  • 支持 3 种数据传输模式,如 Single Block, Multi Block, Multi Block with Linked List

  • 只支持 DMA 作为流控的主控方;不支持外设作为主控

  • 内部含有 8 个逻辑通道,每个通道支持优先级独立配置,Channel0~1 FIFO 深度为 64 Bytes,其余 2~7 Channel FIFO 深度为 16 Bytes;

  • 支持 Gather/Scatter 聚合和分散搬运

  • 支持 32bit 内部计数位宽

  • 支持中断控制

外设DMA Request信号到AHB DMA通道的映射

AHB DMA 控制器的每个通道都可以配置为响应特定的外设请求信号,该外设请求信号来自于DMAMUX模块的输出。每个 DMA 控制器有 8 个 逻辑通道,每个通道可以配置为响应不同的外设请求信号。以下是每个 DMA 控制器的通道与外设请求信号的映射关系:

../_images/dmamux.png

如果需要使用 DMA 控制器的通道来响应外设请求信号,需要先配置 DMAMUX 模块。DMAMUX 模块负责将外设请求信号映射到 DMA 控制器的通道上。

DMAMUX模块的配置参考 DMAMUX配置:

备注

M2M类型的传输不需要外设请求信号,因此不需要配置DMAMUX。

Scatter/Gather功能

Scatter 功能是指从通道中读取数据并分散存储到多个非连续的缓冲区中; Gather 功能则是将多个非连续缓冲区中的数据聚集起来,传输到一个目标地址,通常是一个连续的内存空间或设备地址。

如下图所示,从A0地址开始,需要每搬移4个DWORD数据到D0、D1、D2、D3地址后,间隔1个DWORD数据,再搬移4个DWORD数据到D4、D5、D6、D7地址。

../_images/dma_source_gather.png

对应的软件配置为:

// 设置 间隔 1个长度, count为4个长度, 使能gather功能
AHBDMA_setSourceGather(&chanInit, 1, 4, ENABLE);

如下图所示,需要将连续的数据D0~D11搬移到A0地址开始的内存中。现将D0~D3搬移到A0~A3,然后间隔16个单位长度再搬移D4~D7到A4~A7,最后搬移D8~D11到A8~A11。

../_images/dma_dest_scatter.png

对应的软件配置为:

// 设置 间隔 16个长度, count为4个长度, 使能scatter功能
AHBDMA_setDestinationScatter(&chanInit, 16, 4, ENABLE);

通道优先级说明

通道优先级配置寄存器为 CFGx的CH_PRIOR字段,数字越大,优先级越高。 API配置为 AHBDMA_initChannelStruct 结构体中的 prior参数。

  • 每个通道的源端和目的端继承该通道的优先级,两者优先级相同

  • 当多个请求竞争同一个 AHB 主机接口时:

  • 优先选择当前最高优先级中处于活动状态的请求

  • 若多个请求具有相同优先级,则通道编号较小的获得授权(例如 CH0 优先于 CH1)

  • 若某通道启用了通道锁定(LOCK_CH),则锁定期间该通道会独占主接口,此时优先级可能被暂时覆盖

  • 优先级仅影响仲裁顺序,不改变数据传输的完整性

软件配置流程

M2P配置流程

  1. 使能模块 调用 AHBDMA_enableModule() 传入AHBDMAx

  2. 通道配置参数结构体初始化 调用 AHBDMA_initChannelStruct() 对结构体进行初始化

  3. 配置DMAMUX

  4. 设置内存到外设(M2P)的默认配置 调用 AHBDMA_setDefaultM2P() 传入相关参数

  5. 初始化通道

  6. 使能通道 调用 AHBDMA_enableChannel() 传入AHBDMAx及通道号

P2P配置流程

  1. 使能模块 调用 AHBDMA_enableModule() 传入AHBDMAx

  2. 通道配置参数结构体初始化 调用 AHBDMA_initChannelStruct() 对结构体进行初始化

  3. 配置DMAMUX

  4. 设置外设到外设(P2P)的默认配置 调用 AHBDMA_setDefaultP2P() 传入相关参数

  5. 初始化通道

  6. 使能通道 调用 AHBDMA_enableChannel() 传入AHBDMAx及通道号

其他搬运模式配置也都类似

应用示例

API Reference

Header File

Functions

DRV_Status AHBDMA_enableModule(AHBDMA_Type *AHBDMAx)

Enable AHBDMA device.

参数:

AHBDMAx – AHBDMA peripheral address

返回:

DRV_Status DRV_OK: enable success or have been enabled

DRV_Status AHBDMA_disableModule(AHBDMA_Type *AHBDMAx)

Disable AHBDMA device.

参数:

AHBDMAx – AHBDMA peripheral address

返回:

DRV_Status DRV_OK: disable success DRV_TIMEOUT: disable failed because of DMA transfer dost not end during timeout time

void AHBDMA_initChannel(AHBDMA_Type *AHBDMAx, const AHBDMA_Ch_Init_TypeDef *init, uint32_t ch)

init channel

参数:
  • AHBDMAx – AHBDMA peripheral address

  • init – channel initialized parameter structure

  • ch – AHBDMA channel

DRV_Status AHBDMA_deInitChannel(AHBDMA_Type *AHBDMAx, uint32_t ch)

Deinit channel.

参数:
  • AHBDMAx – AHBDMA peripheral address

  • ch – AHBDMA channel

返回:

DRV_Status DRV_OK: deinit success DRV_TIMEOUT: deinit failed because of DMA transfer dost not end during timeout time

void AHBDMA_initChannelStruct(AHBDMA_Ch_Init_TypeDef *init)

Init the channel initial structure.

参数:

init – channel initialized parameter structure

DRV_Status AHBDMA_enableChannel(AHBDMA_Type *AHBDMAx, uint32_t ch)

Enable channel.

参数:
  • AHBDMAx – AHBDMA peripheral address

  • ch – AHBDMA channel

返回:

DRV_Status DRV_OK: enable success or have been enabled

DRV_Status AHBDMA_disableChannel(AHBDMA_Type *AHBDMAx, uint32_t ch)

Disable channel.

参数:
  • AHBDMAx – AHBDMA peripheral address

  • ch – AHBDMA channel

返回:

DRV_Status DRV_OK: disable success DRV_TIMEOUT: disable failed because of DMA transfer dost not end during timeout time

void AHBDMA_suspendChannel(AHBDMA_Type *AHBDMAx, uint32_t ch)

Suspend channel.

参数:
  • AHBDMAx – AHBDMA peripheral address

  • ch – AHBDMA channel

void AHBDMA_resumeChannel(AHBDMA_Type *AHBDMAx, uint32_t ch)

Resume channel.

参数:
  • AHBDMAx – AHBDMA peripheral address

  • ch – AHBDMA channel

uint32_t AHBDMA_findFreeChannel(AHBDMA_Type *AHBDMAx)

Find a free channel.

参数:

AHBDMAx – AHBDMA peripheral address

返回:

uint32_t AHBDMA_CH_ERR: No free channel channel ID: The free channel ID

bool AHBDMA_isChannelFree(AHBDMA_Type *AHBDMAx, uint32_t ch)

Return specified AXIDMA transfer channel is free or not.

参数:
  • AHBDMAx – AHBDMA peripheral address

  • ch – AXIDMA transfer channel index

返回:

true channel is under a transfer

返回:

false channel is not initialized or have completed tansfer

bool AHBDMA_isChannelFifoEmpty(AHBDMA_Type *AHBDMAx, uint32_t ch)

Judge channel fifo is empty or not.

参数:
  • AHBDMAx – AHBDMA peripheral address

  • ch – AHBDMA channel

返回:

true channel fifo is empty

返回:

false channel fifo is not empty

DRV_Status AHBDMA_setDefaultM2M(AHBDMA_Ch_Init_TypeDef *init, uint32_t srcAddress, uint32_t dstAddress, uint32_t size)

Get default settings for m2m mode, single-block transmitting mode.

参数:
  • init – channel initialized parameter structure

  • srcAddress – source address

  • dstAddress – destination address

  • size – transfer size for single block

返回:

DRV_Status DRV_OK: success DRV_PARAM_ERR: Fail because of transfer size is greater than the maximum or is zero

DRV_Status AHBDMA_setDefaultM2P(AHBDMA_Ch_Init_TypeDef *init, uint32_t srcAddress, uint32_t dstAddress, uint32_t size, uint8_t dstPeripIF)

Get default settings for m2p mode, single-block transmitting mode.

参数:
  • init – channel initialized parameter structure

  • srcAddress – source address

  • dstAddress – destionation peripheral address

  • size – transfer size for single block

  • dstPeripIF – destination peripheral channel

返回:

DRV_Status DRV_OK: success DRV_PARAM_ERR: Fail because of transfer size is greater than the maximum or is zero

DRV_Status AHBDMA_setDefaultP2M(AHBDMA_Ch_Init_TypeDef *init, uint32_t srcAddress, uint32_t dstAddress, uint32_t size, uint8_t srcPeripIF)

Get default settings for p2m mode, single-block transmitting mode.

参数:
  • init – channel initialized parameter structure

  • srcAddress – source peripheral address

  • dstAddress – destionation address

  • srcPeripIF – source peripheral channel index

  • size – transfer size for single block

返回:

DRV_Status DRV_OK: success DRV_PARAM_ERR: Fail because of transfer size is greater than the maximum or is zero

DRV_Status AHBDMA_setDefaultP2P(AHBDMA_Ch_Init_TypeDef *init, uint32_t srcAddress, uint32_t dstAddress, uint32_t size, uint8_t srcPeripIF, uint8_t dstPeripIF)

Get default settings for p2p mode, single-block transmitting mode.

参数:
  • init – channel initialized parameter structure

  • srcAddress – source peripheral address

  • dstAddress – destionation peripheral address

  • size – transfer size

  • srcPeripIF – source peripheral channel

  • dstPeripIF – destination peripheral channel

返回:

DRV_Status DRV_OK: success DRV_PARAM_ERR: Fail because of transfer size is greater than the maximum or is zero

DRV_Status AHBDMA_setMultiBlock(AHBDMA_Ch_Init_TypeDef *init, uint8_t sarUpdateMethod, uint8_t darUpdateMethod, uint32_t llp)

Multi-Block transfer parameter set.

参数:
  • init – channel initialized parameter structure

  • sarUpdateMethod – SAR register update metheod in multi transfer

  • darUpdateMethod – DAR register update metheod in multi transfer

  • llp – link-list pointer

返回:

DRV_Status DRV_OK: success DRV_INVALID: sarUpdateMethod and darUpdateMethod do match

void AHBDMA_setSourceGather(AHBDMA_Ch_Init_TypeDef *init, uint32_t gatherInterval, uint32_t gatherCount, ControlStatus status)

Set source gather transfer parameter.

参数:
  • init – LLI initialized parameter structure

  • gatherInterval – source gather interval

  • gatherCount – source gather count

  • status – ENABLE or DISABLE source gather transfer

void AHBDMA_setDestinationScatter(AHBDMA_Ch_Init_TypeDef *init, uint32_t scatterInterval, uint32_t scatterCount, ControlStatus status)

Set source gather transfer parameter.

参数:
  • init – LLI initialized parameter structure

  • scatterInterval – source gather interval

  • scatterCount – source gather count

  • status – ENABLE or DISABLE source gather transfer

void AHBDMA_initLLI(AHBDMA_LLI_TypeDef *lli, const AHBDMA_LLI_Init_TypeDef *init, bool isLastLLI, uint32_t nextLLP)

Init LINK-LIST item.

参数:
  • init[in] LLI initialized parameter structure

  • lli[out] Pointer to link-list item

  • isLastLLI[in] whether is the last link-list item

  • nextLLP[in] Link-list item

void AHBDMA_initLLIStruct(AHBDMA_LLI_Init_TypeDef *init)

Init LLI initial structure.

参数:

init – LLI initialized parameter structure

DRV_Status AHBDMA_setLLIDefaultM2M(AHBDMA_LLI_Init_TypeDef *init, uint32_t srcAddress, uint32_t dstAddress, uint32_t size, ControlStatus srcLLIUpdate, ControlStatus dstLLIUpdate)

Get default settings for LLI M2M mode.

参数:
  • init – LLI initialized parameter structure

  • srcAddress – source peripheral address

  • dstAddress – destionation peripheral address

  • size – transfer size for single block

  • srcLLIUpdate – source LLI update

  • dstLLIUpdate – destination LLI update

返回:

DRV_Status DRV_OK: success DRV_PARAM_ERR: Fail because of transfer size is greater than the maximum or is zero

DRV_Status AHBDMA_setLLIDefaultM2P(AHBDMA_LLI_Init_TypeDef *init, uint32_t srcAddress, uint32_t dstAddress, uint32_t size, ControlStatus srcLLIUpdate, ControlStatus dstLLIUpdate)

Get default settings for LLI M2P mode.

参数:
  • init – LLI initialized parameter structure

  • srcAddress – source peripheral address

  • dstAddress – destionation peripheral address

  • size – transfer size for single block

  • srcLLIUpdate – source LLI update

  • dstLLIUpdate – destination LLI update

返回:

DRV_Status DRV_OK: success DRV_PARAM_ERR: Fail because of transfer size is greater than the maximum or is zero

DRV_Status AHBDMA_setLLIDefaultP2M(AHBDMA_LLI_Init_TypeDef *init, uint32_t srcAddress, uint32_t dstAddress, uint32_t size, ControlStatus srcLLIUpdate, ControlStatus dstLLIUpdate)

Get default settings for LLI P2M mode.

参数:
  • init – LLI initialized parameter structure

  • srcAddress – source peripheral address

  • dstAddress – destionation peripheral address

  • size – transfer size for single block

  • srcLLIUpdate – source LLI update

  • dstLLIUpdate – destination LLI update

返回:

DRV_Status DRV_OK: success DRV_PARAM_ERR: Fail because of transfer size is greater than the maximum or is zero

DRV_Status AHBDMA_setLLIDefaultP2P(AHBDMA_LLI_Init_TypeDef *init, uint32_t srcAddress, uint32_t dstAddress, uint32_t size, ControlStatus srcLLIUpdate, ControlStatus dstLLIUpdate)

Get default settings for LLI P2P mode.

参数:
  • init – LLI initialized parameter structure

  • srcAddress – source peripheral address

  • dstAddress – destionation peripheral address

  • size – transfer size for single block

  • srcLLIUpdate – source LLI update

  • dstLLIUpdate – destination LLI update

返回:

DRV_Status DRV_OK: success DRV_PARAM_ERR: Fail because of transfer size is greater than the maximum or is zero

void AHBDMA_enableChannelInterrupt(AHBDMA_Type *AHBDMAx, uint32_t ch, uint32_t interruptMasks)

Enable AHBDMAx interrupt request for channel [ch].

参数:
  • AHBDMAx – AHBDMA peripheral address

  • ch – AHBDMA channel

  • interruptMasks – DMA interrupt request masks

void AHBDMA_disableChannelInterrupt(AHBDMA_Type *AHBDMAx, uint32_t ch, uint32_t interruptMasks)

Disable AHBDMAx interrupt request for channel [ch].

参数:
  • AHBDMAx – AHBDMA peripheral address

  • ch – AHBDMA channel

  • interruptMasks – DMA interrupt request masks

uint32_t AHBDMA_getTfrInterruptChannelMask(AHBDMA_Type *AHBDMAx)

Get channels that have transfer complete interrupt request.

参数:

AHBDMAx – AHBDMA peripheral address

返回:

uint32_t channel ID masks: The channel ID masks in transfer complete interrupt

uint32_t AHBDMA_getBlockInterruptChannelMask(AHBDMA_Type *AHBDMAx)

Get channels that have block transfer complete interrupt request.

参数:

AHBDMAx – AHBDMA peripheral address

返回:

uint32_t channel ID masks: The channel ID masks in block transfer complete interrupt

uint32_t AHBDMA_getSrctranInterruptChannelMask(AHBDMA_Type *AHBDMAx)

Get channels that have source transfer complete interrupt request.

参数:

AHBDMAx – AHBDMA peripheral address

返回:

uint32_t channel ID masks: The channel ID masks in source transfer complete interrupt

uint32_t AHBDMA_getDsttranInterruptChannelMask(AHBDMA_Type *AHBDMAx)

Get channels that have destionation transfer complete interrupt request.

参数:

AHBDMAx – AHBDMA peripheral address

返回:

uint32_t channel ID masks: The channel ID masks in destionation transfer complete interrupt

uint32_t AHBDMA_getErrInterruptChannelMask(AHBDMA_Type *AHBDMAx)

Get channels that have transfer error interrupt request.

参数:

AHBDMAx – AHBDMA peripheral address

返回:

uint32_t channel ID masks: The channel ID masks in error transfer complete interrupt

void AHBDMA_clearInterruptChannel(AHBDMA_Type *AHBDMAx, uint32_t ch, uint32_t interruptMasks)

Clear AHBDMAx interrupt request for channel [ch].

参数:
  • AHBDMAx – AHBDMA peripheral address

  • ch – AHBDMA channel ID

  • interruptMasks – DMA interrupt request masks

Structures

struct AHBDMA_Ch_Init_TypeDef

AHBDMA channel init structure.

struct AHBDMA_LLI_TypeDef

AHBDMA LLI register structure.

struct AHBDMA_LLI_Init_TypeDef

AHBDMA LLI init structure, including all parameters to fill LLI register structure. member <intEn> is added to control interrupt.

Macros

ICTM_CORE0_TO_DMA_OFFSET
DCTM_CORE0_TO_DMA_OFFSET
AHBDMA_NUM_CHANNELS
AHBDMA_CH_ERR
AHBDMA_CH_0
AHBDMA_CH_1
AHBDMA_CH_2
AHBDMA_CH_3
AHBDMA_CH_4
AHBDMA_CH_5
AHBDMA_CH_6
AHBDMA_CH_7
AHBDMA_MAX_BLOCK_TR_SIZE
AHBDMA_BITS_8
AHBDMA_BITS_16
AHBDMA_BITS_32
AHBDMA_INCREMENTAL
AHBDMA_DECREMENTAL
AHBDMA_FIXED
AHBDMA_BURST_DATA_ITEMS_1
AHBDMA_BURST_DATA_ITEMS_4
AHBDMA_BURST_DATA_ITEMS_8
AHBDMA_BURST_DATA_ITEMS_16
AHBDMA_BURST_DATA_ITEMS_32
AHBDMA_BURST_DATA_ITEMS_64
AHBDMA_BURST_DATA_ITEMS_128
AHBDMA_BURST_DATA_ITEMS_256
AHBDMA_MEM_TO_MEM
AHBDMA_MEM_TO_PER
AHBDMA_PER_TO_MEM
AHBDMA_PER_TO_PER
AHBDMA_CH_PRIORITY_0
AHBDMA_CH_PRIORITY_1
AHBDMA_CH_PRIORITY_2
AHBDMA_CH_PRIORITY_3
AHBDMA_CH_PRIORITY_4
AHBDMA_CH_PRIORITY_5
AHBDMA_CH_PRIORITY_6
AHBDMA_CH_PRIORITY_7
AHBDMA_FIFO_SINGLE
AHBDMA_FIFO_HALF_DEPTH

Data available is greater than or equal to half the fifo depth for destination transfers and space available is greater than half the fifo depth for source transfers. the exceptions are at the end of a burst transaction request or at the end of a block transfer.

AHBDMA_IT_TFR_MASK
AHBDMA_IT_BLOCK_MASK
AHBDMA_IT_SRCTRAN_MASK
AHBDMA_IT_DSTTRAN_MASK
AHBDMA_IT_ERR_MASK
AHBDMA_IF_MEM
AHBDMA_IF_0
AHBDMA_IF_1
AHBDMA_IF_2
AHBDMA_IF_3
AHBDMA_IF_4
AHBDMA_IF_5
AHBDMA_IF_6
AHBDMA_IF_7
AHBDMA_CONTIGUOUS
AHBDMA_RELOAD
AHBDMA_LINKED_LIST