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 控制器的通道与外设请求信号的映射关系:
如果需要使用 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地址。
对应的软件配置为:
// 设置 间隔 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。
对应的软件配置为:
// 设置 间隔 16个长度, count为4个长度, 使能scatter功能
AHBDMA_setDestinationScatter(&chanInit, 16, 4, ENABLE);
通道优先级说明
通道优先级配置寄存器为 CFGx的CH_PRIOR字段,数字越大,优先级越高。 API配置为 AHBDMA_initChannelStruct 结构体中的 prior参数。
每个通道的源端和目的端继承该通道的优先级,两者优先级相同
当多个请求竞争同一个 AHB 主机接口时:
优先选择当前最高优先级中处于活动状态的请求
若多个请求具有相同优先级,则通道编号较小的获得授权(例如 CH0 优先于 CH1)
若某通道启用了通道锁定(LOCK_CH),则锁定期间该通道会独占主接口,此时优先级可能被暂时覆盖
优先级仅影响仲裁顺序,不改变数据传输的完整性
软件配置流程
M2P配置流程
使能模块 调用
AHBDMA_enableModule()传入AHBDMAx通道配置参数结构体初始化 调用
AHBDMA_initChannelStruct()对结构体进行初始化配置DMAMUX
调用
SYSCTRL_findDMAMuxFreeInterface()查找空闲接口;调用
SYSCTRL_configDMAMux()传入AHBDMAx、接口及请求索引
设置内存到外设(M2P)的默认配置 调用
AHBDMA_setDefaultM2P()传入相关参数初始化通道
调用
AHBDMA_findFreeChannel()查找空闲通道;调用
AHBDMA_initChannel()传入AHBDMAx、参数结构体及通道号
使能通道 调用
AHBDMA_enableChannel()传入AHBDMAx及通道号
P2P配置流程
使能模块 调用
AHBDMA_enableModule()传入AHBDMAx通道配置参数结构体初始化 调用
AHBDMA_initChannelStruct()对结构体进行初始化配置DMAMUX
调用
SYSCTRL_findDMAMuxFreeInterface()查找空闲接口1;调用
SYSCTRL_configDMAMux()传入AHBDMAx、接口1及外设源端请求索引调用
SYSCTRL_findDMAMuxFreeInterface()查找空闲接口2;调用
SYSCTRL_configDMAMux()传入AHBDMAx、接口2及外设目的端请求索引
设置外设到外设(P2P)的默认配置 调用
AHBDMA_setDefaultP2P()传入相关参数初始化通道
调用
AHBDMA_findFreeChannel()查找空闲通道;调用
AHBDMA_initChannel()传入AHBDMAx、参数结构体及通道号
使能通道 调用
AHBDMA_enableChannel()传入AHBDMAx及通道号
其他搬运模式配置也都类似
应用示例
内存到内存(M2M)示例:DMA/DMA_M2M。
内存到外设(M2P)示例:DMA/DMA_M2P。
内存到外设(M2P), Multi Block Reload示例:DAC/DAC_DMAWaveGen。
外设到外设(P2P)示例:DMA/DMA_P2P。
分散集合加载示例:DMA/DMA_Scatter_Gather。
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