【应用笔记】TAE32G5800 HRPWM-BurstDMA应用操作指南
1 应用功能介绍
TAE32G5800的HRPWM带有Burst DMA功能。Burst DMA功能并非Burst突发模式,两者并没实际联系。Burst DMA功能主要是实现以下功能:利用突发事件来驱动HRPWM更新主定时器、子定时器x的寄存器。
此方案更新的优势在于可以不在软件介入的情况下,自动更新HRPWM的寄存器。
此方案包含的对象与结构框图如图1.1所示。
Burst DMA由三个对象组成:
▶ Burst DMA触发器定义:定义由哪些PWM事件触发Burst DMA动作启动;
▶ 源地址寄存器:指定DMA通道的源地址,通常使用RAM中的变量数组存储;
▶ 目的寄存器:指定DMA通道的目的地址,更新寄存器的每个bit指示具体的PWM寄存器;
另外,TAE32G5800还提供了Burst DMA动作是否产生更新事件的机制。
2 触发器
触发器指定哪些PWM事件触发Burst DMA动作。Burst DMA的触发源定义如下所示。
表2.1 HRPWM DMA请求汇总
DMA请求 | HRPWM事件 |
DMA支持 |
使能 控制位 |
---|---|---|---|
hrpwm_mst_req
|
同步事件接收 事件 |
支持 |
SYNCDE |
主寄存器更新事件 |
支持 |
MUPDDE |
|
主周期重复事件 |
支持 |
MREPDE |
|
主复位事件 |
支持 |
MRSTDE |
|
主周期事件 |
支持 |
MPERDE |
|
主比较A~D事 件 |
支持 |
MCMPADE |
|
支持 |
MCMPBDE |
||
支持 |
MCMPCDE |
||
支持 |
MCMPDDE |
||
hrpwm_slv0_req hrpwm_slv1_req hrpwm_slv2_req hrpwm_slv3_req hrpwm_slv4_req hrpwm_slv5_req hrpwm_slv6_req hrpwm_slv7_req |
延 迟保护触发事件 |
支持 |
DLYPRTDE |
捕获A和捕获B事件 |
支持 |
CAPADE |
|
支持 |
CAPBDE |
||
周期重复事件 |
支持 |
REPDE |
|
计数复位事 件 |
支持 |
RSTDE |
|
输出A和输出B复位事件 (有效电平到无效电平) |
支持 |
CLRADE |
|
支持 |
CLRBDE |
||
输出A和输出B置位事件 (无效电平到有效电平) |
支持 |
SETADE |
|
支持 |
SETBDE |
||
寄存器更新事件 |
支持 |
UPODDE |
|
周期翻转事件 |
支持 |
PERDE |
|
比较A~D事 件 |
支持 |
CMPADE |
|
支持 |
CMPBDE |
||
支持 |
CMPCDE |
||
支持 |
CMPDDE |
触发的请求分为主PWM请求和子PWM请求,无论哪个请求产生,均会触发一次Burst DMA更新动作。
2.1 主PWM的Burst DMA触发请求定义
主PWM请求在SDK代码内的定义如代码清单2.1和图2.1所示。
代码清单2.1 Burst DMA的主PWM触发源定义
路径:tae32g58xx_ll_hrpwm.h
ypedef enum {
HRPWM_MST_DMA_NONE = 0, /*!< Master DMA None */
HRPWM_MST_DMA_CMPA = BIT(16), /*!< Master DMA Compare A */
HRPWM_MST_DMA_CMPB = BIT(17), /*!< Master DMA Compare B */
HRPWM_MST_DMA_CMPC = BIT(18), /*!< Master DMA Compare C */
HRPWM_MST_DMA_CMPD = BIT(19), /*!< Master DMA Compare D */
HRPWM_MST_DMA_PRD = BIT(20), /*!< Master DMA Period */
HRPWM_MST_DMA_SYNCIN = BIT(21), /*!< Master DMA Sync In */
HRPWM_MST_DMA_UPD = BIT(22), /*!< Master DMA Update */
HRPWM_MST_DMA_RST = BIT(23), /*!< Master DMA Reset */
HRPWM_MST_DMA_REP = BIT(24), /*!< Master DMA Repetition */
} HRPWM_Mst_DMAETypeDef;
赋值定义如代码清单2.2所示。
代码清单2.2 主PWM的Burst DMA触发源赋值代码
HRPWM_TmrBaseCfgTypeDef master_pwm_tmr_base_cfg;
memset((void *)&master_pwm_tmr_base_cfg, 0x00, sizeof(master_pwm_tmr_base_cfg));
master_pwm_tmr_base_cfg.dma_en_msk = HRPWM_MST_DMA_PRD;
2.2 子PWM的Burst DMA触发请求定义
子PWM请求在SDK代码内的定义如代码清单2.3所示。
代码清单2.3 Burst DMA的子PWM触发源定义
路径:tae32g58xx_ll_hrpwm.h
typedef enum {
HRPWM_SLV_DMA_NONE = 0, /*!< Slave DMA None */
HRPWM_SLV_DMA_CMPA = BIT(16), /*!< Slave DMA Compare A */
HRPWM_SLV_DMA_CMPB = BIT(17), /*!< Slave DMA Compare B */
HRPWM_SLV_DMA_CMPC = BIT(18), /*!< Slave DMA Compare C */
HRPWM_SLV_DMA_CMPD = BIT(19), /*!< Slave DMA Compare D */
HRPWM_SLV_DMA_PRD_RO = BIT(20), /*!< Slave DMA Period/Roll-Over */
HRPWM_SLV_DMA_UPD = BIT(21), /*!< Slave DMA Update */
HRPWM_SLV_DMA_OUTA_SET = BIT(22), /*!< Slave DMA OutA Set */
HRPWM_SLV_DMA_OUTA_CLR = BIT(23), /*!< Slave DMA OutA Clear */
HRPWM_SLV_DMA_OUTB_SET = BIT(24), /*!< Slave DMA OutB Set */
HRPWM_SLV_DMA_OUTB_CLR = BIT(25), /*!< Slave DMA OutB Clear */
HRPWM_SLV_DMA_RST = BIT(26), /*!< Slave DMA Reset */
HRPWM_SLV_DMA_REP = BIT(27), /*!< Slave DMA Repetition */
HRPWM_SLV_DMA_CAPA = BIT(28), /*!< Slave DMA Capture A */
HRPWM_SLV_DMA_CAPB = BIT(29), /*!< Slave DMA Capture B */
HRPWM_SLV_DMA_DLY_PROT = BIT(30), /*!< Slave DMA Delay Protection */
} HRPWM_Slv_DMAETypeDef;
赋值定义如代码清单2.4所示。
代码清单2.4 子PWM的Burst DMA触发源赋值代码
HRPWM_TmrBaseCfgTypeDef user_hrpwm_tmr_base_cfg;
memset((void *)&user_hrpwm_tmr_base_cfg, 0x00, sizeof(user_hrpwm_tmr_base_cfg));
user_hrpwm_tmr_base_cfg.dma_en_msk = HRPWM_SLV_DMA_NONE;
3 源地址配置
存放源数据的数组定义如代码清单3.1所示,burst_dma_buf数组的每个单元与使能DMA更新的寄存器一一对应。
代码清单3.1 源缓冲区对象
volatile uint32_t burst_dma_buf[9] = {0x600, 0x100, 0x200, 0x300, 0x400,
0x400, 0x100, 0x200,
0x400};
__LL_HRPWM_Comm_BurstDMAAddr_Set(HRPWM, burst_dma_buf);
__LL_HRPWM_Comm_BurstDMAAddr_Set()函数是把存放源数据的数组地址填写入BDMADR寄存器,寄存器定义如图3.1所示。
4 目的地址配置
目的地址配置是指在Burst DMA动作中的哪些寄存器更新使能,分为主PWM使能与子PWM使能。
4.1 主PWM的DMA更新使能
主PWM的DMA更新使能位定义如代码清单4.1所示。
代码清单4.1 主PWM的DMA更新使能位
路径:tae32g58xx_ll_hrpwm.h
typedef enum {
HRPWM_COMM_BURST_DMA_MST_REG_UPD_NONE = 0,
HRPWM_COMM_BURST_DMA_MST_REG_UPD_MCR0 = BIT(0),
HRPWM_COMM_BURST_DMA_MST_REG_UPD_MCR1 = BIT(1),
HRPWM_COMM_BURST_DMA_MST_REG_UPD_MISR = BIT(2),
HRPWM_COMM_BURST_DMA_MST_REG_UPD_MDIER = BIT(3),
HRPWM_COMM_BURST_DMA_MST_REG_UPD_MCNTR = BIT(4),
HRPWM_COMM_BURST_DMA_MST_REG_UPD_MPER = BIT(5),
HRPWM_COMM_BURST_DMA_MST_REG_UPD_MREP = BIT(6),
HRPWM_COMM_BURST_DMA_MST_REG_UPD_MCMPAR = BIT(7),
HRPWM_COMM_BURST_DMA_MST_REG_UPD_MCMPBR = BIT(8),
HRPWM_COMM_BURST_DMA_MST_REG_UPD_MCMPCR = BIT(9),
HRPWM_COMM_BURST_DMA_MST_REG_UPD_MCMPDR = BIT(10),
} HRPWM_Comm_BurstDMAMstRegUpdETypeDef;
相关寄存器描述如图4.1所示。
具体操作代码如下所示。
代码清单4.2 指定主PWM的DMA使能
uint32_t mst_reg_upd;
mst_reg_upd = HRPWM_COMM_BURST_DMA_MST_REG_UPD_MPER |
HRPWM_COMM_BURST_DMA_MST_REG_UPD_MCMPAR |
HRPWM_COMM_BURST_DMA_MST_REG_UPD_MCMPBR |
HRPWM_COMM_BURST_DMA_MST_REG_UPD_MCMPCR |
HRPWM_COMM_BURST_DMA_MST_REG_UPD_MCMPDR;
__LL_HRPWM_Comm_BurstDMAMstPWMRegUpd_Set(HRPWM, mst_reg_upd);
4.2 子PWM的DMA更新使能
子PWM的DMA更新使能位定义如代码清单4.3所示。
代码清单4.3 子PWM的DMA更新使能位
typedef enum {
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_NONE = 0,
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CR0 = BIT(0),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CR1 = BIT(1),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_ISR = BIT(2),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_DIER = BIT(3),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CNTR = BIT(4),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_PERR = BIT(5),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_REPR = BIT(6),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CMPAR = BIT(7),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CMPBR = BIT(8),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CMPCR = BIT(9),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CMPDR = BIT(10),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CAPAR = BIT(11),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CAPBR = BIT(12),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_DTR = BIT(13),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_SETAR = BIT(14),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CLRAR = BIT(15),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_SETBR = BIT(16),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CLRBR = BIT(17),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_EEFR0 = BIT(18),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_EEFR1 = BIT(19),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_EEFR2 = BIT(20),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_RSTR = BIT(21),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_RSTER = BIT(22),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CHPR = BIT(23),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CAPACR = BIT(24),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CAPACER = BIT(25),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CAPBCR = BIT(26),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CAPBCER = BIT(27),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_OUTR = BIT(28),
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_FLTR = BIT(29),
} HRPWM_Comm_BurstDMASlvRegUpdETypeDef;
相关寄存器描述如图4.2所示。
具体操作代码如下所示。
代码清单4.4 指定子PWM的DMA使能
uint32_t slv_reg_upd[HRPWM_SLV_PWM_NUMS];
slv_reg_upd[0] = HRPWM_COMM_BURST_DMA_SLV_REG_UPD_PERR |
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CMPAR |
HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CMPBR;
slv_reg_upd[1] = HRPWM_COMM_BURST_DMA_SLV_REG_UPD_CMPAR;
__LL_HRPWM_Comm_BurstDMASlvPWMxRegUpd_Set(HRPWM, HRPWM_SLV_PWM_0, slv_reg_upd[0]);
__LL_HRPWM_Comm_BurstDMASlvPWMxRegUpd_Set(HRPWM, HRPWM_SLV_PWM_1, slv_reg_upd[1]);
5 Burst DMA更新顺序
Burst DMA从固定地址buf中取出数据,推到各个不同的寄存器上,推送顺序如所示。

硬件检测顺序为:BDMCPR->BDUPR0->BDUPR1->……->BDUPR7,然后在每个寄存器内从bit0->bit1->bitx。
结合代码分析,在代码清单4.2中指定了主PWM更新MPER(Bit5)、MCMPAR(Bit7)、MCMPBR(Bit8)、MCMPCR(Bit9)、MCMPDR(Bit10)。所以代码清单3.1中的burst_dma_buf[0]对应于MPER;burst_dma_buf[1]对应于MCMPAR……
6 FAQ 答疑环节
Q:DMA的数组长度设置问题,如果目标与源的长度不一致会怎么样?
A:DMA搬运长度由图1.1中,紫色部分的BDMUPR、BDUPR0~7决定,源寄存器内保存的只是一个内存地址。源寄存器的功能是告诉DMA模块,从这个地址开始搬运数据,所以对DMA模块而言,只管搬运一次挪动指针到下一个位置,至于这个位置是否在Buf内,DMA本身是无法检测的(因为上述方案中,填入的只有触发器、源的地址设置、目的地的地址设置,而没有对源的长度的设置或者检查)。
所以DMA的搬运可能遇到一种情况,在DMA传输的应用中,尤其是外设到内存中,出现数据异常时,需要关注传输的长度。当DMA传输长度超过内存中的Buf,那么超过部分会覆盖掉Buf后面紧接的地址,体现现象为,某些变量无缘由地发生变化。
Q:这个HRPWM Burst DMA功能应用场合是什么?
A:这个功能主要适用于一次批量更新大量PWM寄存器,使用硬件事件触发DMA自动传输。对比于使用定时器更新寄存器的方式,优势在于不需要占用中断资源,大量寄存器更新时也不需要耗费大量指令去逐一更新寄存器。缺点在于一次DMA触发就会做完全部更新,无法分开不同事件独立更新寄存器的功能。