6678DSP edma和中断配置

edma负责数据搬移,在DSP信号处理中还是非常重要的

1、6678 edma三维传输能力方便传输矩阵数据,在雷达数据处理中需要时域到频域的变换,edma可以方便的将矩阵数据转置。

6678DSP edma和中断配置_第1张图片

6678DSP edma和中断配置_第2张图片

2、edma能力集

6678DSP edma和中断配置_第3张图片

6678DSP edma和中断配置_第4张图片

3、edma控制器框图

6678DSP edma和中断配置_第5张图片

4、中断控制器

6678DSP edma和中断配置_第6张图片

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)) 

6678DSP edma和中断配置_第7张图片

3)edma中断事件从CIC0 CIC1输入

6678DSP edma和中断配置_第8张图片

4)CCINTx对应Shadow Regionx

6678DSP edma和中断配置_第9张图片

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;

你可能感兴趣的:(dsp开发)