先楫SDK组件系列-DMA管理器dma_mgr
该系列主要讲解hpm_sdk的components,也就是组件包,不同于middleware第三方中间件,components是hpmicro自身开发的组件,独立服务于sdk,目前主要集中于外设和模块组件,比如多媒体相关的panel和camera、touch、codec;外设相关的adc、spi、uart、dma等等。 截至hpm_sdk 1.4,有以下的组件包
组件包的存在,可以让用户减少工作量,统一某一种模块使用,无需理会底层操作。比如本文需要介绍的dma管理器---dma_mgr。
先楫的产品目前覆盖了几大产品线--hpm67/64系列、hpm63系列、hpm62系列、hpm53系列、hpm68系列,不单产品线逐渐丰富,而且外设模块也根据客户市场需求不断更新迭代,而从软件生态来看,先楫一直都是一套sdk就能开发所有产品,这对于用户来说,方便管理以及快速切换不同产品,但同时也带来学习成本的增加,比如单纯从DMA模块来看,刚接触的用户或者老用户可能还不知道DMA模块的功能升级,也就是从最初的DMA-V1升级到DMA-V2版本。而组件的DMA管理器dma_mgr,也是基于这个背景下应运而生。
先楫的DMA模块,分为HDMA和XDMA,分别处于不同总线,总线位宽也不一样,HDMA为32位宽,而XDMA可以64位,另外也不是所有系列SOC都支持XDMA。每个模块下有不同的通道,共用一个中断源,也就是同一个中断入口。
先楫的DMA模块,分为DMAV1和DMAV2,在hpm_sdk1.4中,对于DMAV2所在的soc中,可以在sdk中查到,目前支持DMA-V2的分别是HPM53系列和HPM68系列,也就说明,后续发布的系列应该也是DMAV2或者更新的DMA版本。
而在dma_mgr的头文件可知,DMAV2相比DMAV1多了以下功能:
对应手册可知,相比DMAV1,多了循环模式、burst请求可配置、可改变burst数量、支持传输一半中断请求。更多功能差异可对比下以上SOC系列的UM手册,这里不做更多的阐述说明。
对于用户来说,如果使用了dma_mgr,已经管理了DMA模块,是不需要关心以上的相同点和差异点,只需要按照组件中的API使用即可。
该头文件主要定义了相关宏、结构体、API,覆盖了DMA模块的基本使用方法。
1、由于DMA版本的差异性,需要再定义一套相关的操作宏,比如DMAV1不支持传输一半中断,那么DMAV1的定义就是0
对于其他的相同点,重新再定义一套宏,以DMA_MGR_作为前缀。
2、dma管理器定义了一个DMA资源对象结构体,里面包含DMA的基地址、所使用的DMA通道,以及中断号。
3、dma管理器同样也定义了dma的配置参数,除了常规的DMA配置,需要特别说明的是DMA支持链式传输linke_ptr,以及DMA请求路由器DMAMUX相关
linke_ptr:DMA链式传输,简答来说,当前的DMA传输完毕之后,如果该链式地址有效,那么把该地址的描述符硬件重新赋值到DMA控制器的配置上,实现一种链式的传输,而该链式的描述符如手册说明:
DMAMUX,分别是en_dmamux和dmamux_src,DMA 请求路由器的功能是实现外设 DMA 请求对 DMA 控制器各个通道的灵活动态映射,使得任意外设可以发送 DMA 请求给任意 DMA 控制器的任意通道。比如在HPM5300中,SPI的发送DMA请求对应的以下:
在sdk的sample中,对于该组件的使用例子是sample/dma_manager,里面几乎包括了DMA管理器这个组件的使用,需要了解的可以自行查看,在readme可知,dma管理器组件已经内置了中断处理函数,统一管理中断,用户的应用程序不能再声明中断函数,否则会报重复定义错误。
1、定义全局DMA通道资源实例数组,需要多少个DMA通道就定义多少个数组成员,比如这里需要SPI的发送和接收DMA,那么就是需要两个。
2、初始化DMA管理器 dma_mgr_init,主要内部初始化DMA管理器的内部管理全局变量成员。
3、使用dma_mgr_request_resource API注册DMA通道资源实例,需要把定义的DMA通道资源实例注册到DMA管理器上,如果管理器有剩余的DMA通道,那么就会赋予相关的DMA基地址、DMA通道号等信息。
4、使用dma_mgr_setup_channel配置DMA通道资源示例,比如配置SPI的DMA发送,使用dma_mgr_enable_channel API进行DMA通道使能传输。