edma负责数据搬移,在DSP信号处理中还是非常重要的
1、6678 edma三维传输能力方便传输矩阵数据,在雷达数据处理中需要时域到频域的变换,edma可以方便的将矩阵数据转置。
2、edma能力集
3、edma控制器框图
4、中断控制器
1)CPU中断控制器支持128个系统事件可编程到12个中断向量 CPUINT4 - CPUINT15
2)128个系统事件有部分来源于CIC0和CIC1,可以看做是二级中断控制器
如系统事件21来源于CIC0_OUT(32+0+11*n) Or CIC1_OUT(32+0+11*(n-4))
3)edma中断事件从CIC0 CIC1输入
4)CCINTx对应Shadow Regionx
5)中断事件映射
CC1 Region0产生的edma完成中断对应CIC0的事件8
将CIC0的事件8映射到CIC0_OUT32,则对应中断控制器系统事件21
将系统事件21映射到中断向量CPUINT4,则完成edma完成中断的配置
#define EDMA_CPY_VECTID 4
#define EDMA_CPY_EVENTID(coreId) (21)
#define EDMA_CPY_SYSINTID(coreId) (8+(coreId))
#define EDMA_CPY_CICINST(coreId) (((coreId) < 4)?(CSL_CP_INTC_0):(CSL_CP_INTC_1))
#define EDMA_CPY_CICOUT(coreId) (((coreId) < 4)?(32+11*(coreId)):(32+11*((coreId)-4)))
5、edma配置,CC1为例
#define EDMA3CC_INST CSL_EDMA3CC_1
1)edma有8个Shadow region,每个核分配一个
#define EDMA_CPY_REGION(coreId) (CSL_EDMA3_REGION_0+(coreId))
2)edma通道分配,CC1支持64通道
#define EDMA_CPY_CHANNEL(coreId) (1+(coreId))
3)Param set分配,CC1支持512组
EDMA_CPY_PARAM_RELOAD可以用于link模式
#define EDMA_CPY_PARAM(coreId) (10+(coreId))
#define EDMA_CPY_PARAM_RELOAD(coreId) (18+(coreId))
4)Param set edma传输完成控制字,用于产生edma完成中断
#define EDMA_CPY_TCC(coreId) (1+(coreId))
5)初始化配置
CSL_Edma3Handle hModule;
CSL_Edma3Obj edmaObj;
CSL_Edma3ChannelHandle hEdmaChannel_EdmaCpy;
CSL_Edma3ChannelObj chObj_EdmaCpy;
ERR DSP_edma_init()
{
CSL_Edma3CmdIntr regionIntr;
CSL_Edma3CmdDrae regionAccess;
CSL_Edma3ChannelAttr chAttr;
CSL_Status status;
CSL_Edma3Context context;
UINT coreId;
coreId = GetCoreId();
if(CSL_edma3Init(&context) != CSL_SOK)
{
PRT("DSP_edma_init: Edma module initialization failed\n");
return DSP_EDMA_INIT_ERR;
}
// 打开EDMA 1
hModule = CSL_edma3Open(&edmaObj, EDMA3CC_INST, NULL, &status);
if((hModule == NULL) || (status != CSL_SOK))
{
PRT("DSP_edma_init: EdmaCC module open failed\n");
return DSP_EDMA_INIT_ERR;
}
/*----DMA COPY CH----*/
//Region
regionAccess.region = EDMA_CPY_REGION(coreId);
regionAccess.drae = 1 << (EDMA_CPY_CHANNEL(coreId));
regionAccess.draeh = 0x0 ;
status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_DMAREGION_ENABLE,®ionAccess);
if(status != CSL_SOK)
{
PRT("DSP_edma_init: Edma region enable command failed\n");
return DSP_EDMA_INIT_ERR;
}
// Channel open
chAttr.regionNum = EDMA_CPY_REGION(coreId);
chAttr.chaNum = EDMA_CPY_CHANNEL(coreId);
hEdmaChannel_EdmaCpy = CSL_edma3ChannelOpen(&chObj_EdmaCpy, EDMA3CC_INST, &chAttr, &status);
if((hEdmaChannel_EdmaCpy == NULL) || (status != CSL_SOK))
{
PRT("DSP_edma_init: Edma channel open failed\n");
return DSP_EDMA_INIT_ERR;
}
// 选择事件通道
if(CSL_edma3HwChannelSetupQue(hEdmaChannel_EdmaCpy, EDMA_CPY_QUE(coreId)) != CSL_SOK)
{
PRT("DSP_edma_init: Edma channel setup queue failed\n");
return DSP_EDMA_INIT_ERR;
}
// Enable interrupts
regionIntr.region = EDMA_CPY_REGION(coreId) ;
regionIntr.intr = 1 << (EDMA_CPY_TCC(coreId));
regionIntr.intrh = 0x0;
status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTR_ENABLE,®ionIntr);
if(status != CSL_SOK)
{
PRT("DSP_edma_init: Edma interrupt enable command failed\n");
return DSP_EDMA_INIT_ERR;
}
/* EDMA 中断配置 */
EdmaIntCfg();
RET_OK;
}
void EdmaIntCfg()
{
UINT intNum;
UINT eventId;
UINT coreId;
Hwi_Params params;
coreId = GetCoreId();
/* EDMA CPY */
CpIntc_clearSysInt(EDMA_CPY_CICINST(coreId), EDMA_CPY_SYSINTID(coreId));
CpIntc_dispatchPlug(EDMA_CPY_SYSINTID(coreId), (CpIntc_FuncPtr)IsrEdmaCpy, (UArg)hModule, TRUE);
CpIntc_mapSysIntToHostInt(EDMA_CPY_CICINST(coreId), EDMA_CPY_SYSINTID(coreId), EDMA_CPY_CICOUT(coreId));
/* Enable the Host Interrupt. */
CpIntc_enableHostInt(EDMA_CPY_CICINST(coreId), EDMA_CPY_CICOUT(coreId));
/* Enable the System Interrupt */
CpIntc_enableSysInt(EDMA_CPY_CICINST(coreId), EDMA_CPY_SYSINTID(coreId));
/* Get the event id associated with the host interrupt. */
eventId = CpIntc_getEventId(EDMA_CPY_CICOUT(coreId));
/* Initialize the Hwi parameters */
Hwi_Params_init(¶ms);
/* Host interrupt value*/
params.arg = EDMA_CPY_CICOUT(coreId);
/* Set the GEM event id in the params */
params.eventId = eventId;
/* Enable the Hwi */
params.enableInt = TRUE;
/* Specify the interrupt vector number */
intNum = EDMA_CPY_VECTID;
/* When using CpIntc, you must plug the Hwi fxn with CpIntc_dispatch */
/* so it knows how to process the CpIntc interrupts.*/
Hwi_create(intNum, &CpIntc_dispatch, ¶ms, NULL);
}
6、edma搬移数据
一组雷达数据,脉压后的复数一个点8字节,距离维delayNum距离单元,频域维fftNum脉冲积累
MTD处理,做fftNum点FFT,此时需要先将脉压数据转置
#define ELEM_SIZE (8)
edmaInCtrl.acnt = ELEM_SIZE;
edmaInCtrl.bcnt = delayNum;
edmaInCtrl.ccnt = fftNum;
edmaInCtrl.src_bindex = ELEM_SIZE;
edmaInCtrl.src_cindex = delayNum * ELEM_SIZE;
edmaInCtrl.dst_bindex = fftNum * ELEM_SIZE;
edmaInCtrl.dst_cindex = ELEM_SIZE;
edmaInCtrl.src = (void *)dataBuf;
edmaInCtrl.dst = (void *)ramBuf;
MTD处理后,需要在距离维做CFAR,则需要将MTD后的数据转置
edmaOutCtrl.acnt = ELEM_SIZE;
edmaOutCtrl.bcnt = fftNum;
edmaOutCtrl.ccnt = delayNum;
edmaOutCtrl.src_bindex = ELEM_SIZE;
edmaOutCtrl.src_cindex = fftNum * ELEM_SIZE;
edmaOutCtrl.dst_bindex = delayNum * ELEM_SIZE;
edmaOutCtrl.dst_cindex = ELEM_SIZE;
edmaOutCtrl.src = (void *)cfarDataBuf;
edmaOutCtrl.dst = (void *)cfarInBuf;