Hi
I am trying to setup 10 EDMA channels on my custom C6657 board
The first five channels are normal EDMA channels that are chained together The chain is triggered by an event on GPIO1 and the last channel generates a transfer complete interrupt. These channels are used for reading data from the EMIF16 interface
The next four are QDMA channels that are used for writing data to EMIF16 interface
The last channel is a normal EDMA thannel that runs independently of the other, and it is used for writing some other data to a DualportRam on the EMIF16 interface.
Up until now I have only used 3 channels in the chain and when I did that I did not have any problems with my setup. But after adding two more channels to my chain I get an error when I request the last channel using the EDMA3_DRV_requestChannel() to open the last EDMA channel.
The error I get is EDMA3_RM_E_ALL_RES_NOT_AVAILABLE
and it comes from the function EDMA3_RM_Result EDMA3_RM_allocResource(EDMA3_RM_Handle hEdmaResMgr, EDMA3_RM_ResDesc *resObj) (in edma3resmgr.c)
Can someone please explain to me what I am doing wrong, and how I can solve the problem.
I have attached the source file that I use for settnig up my EDMA controller
I use
edma3_lld_02_11_05_02
bios_6_41_00_26
CCSV 6.0.1
Thanks
Jens
#include <xdc/std.h> #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Task.h> #include <ti/sysbios/knl/Semaphore.h> #include <string.h> #include "sample.h" #include "app_pe66.h" #include "VpcTypes.h" #include "FPGA_FDSP.h" /* definitions of datastructures that are to be read from EMIF16 */ #include "EDMA_Drv.h" #include "framework_dspbios_platform.h" #include "IO_Common/Driver_FDSP/DebugPort_Driver.h" #include "profiler/sbm_profiler.h" typedef union { struct { uint32 SAM :1; //* (Bit 0) EDMA3_DRV_OPT_FIELD_SAM // EDMA3_DRV_ADDR_MODE_INCR = 0, // EDMA3_DRV_ADDR_MODE_FIFO = 1 uint32 DAM :1; //* (Bit 1) EDMA3_DRV_OPT_FIELD_DAM // EDMA3_DRV_ADDR_MODE_INCR = 0, // EDMA3_DRV_ADDR_MODE_FIFO = 1 uint32 SYNCDIM :1; //* (Bit 2) EDMA3_DRV_OPT_FIELD_SYNCDIM // EDMA3_DRV_SYNC_A = 0 , // EDMA3_DRV_SYNC_AB = 1 uint32 STATIC :1; //* (Bit 3) EDMA3_DRV_OPT_FIELD_STATIC // EDMA3_DRV_STATIC_DIS = 0, // EDMA3_DRV_STATIC_EN = 1 uint32 bit4_7 :4; //* (Bit 4-7) reserved uint32 FWID :3; //* (Bit 8-10) EDMA3_DRV_OPT_FIELD_FWID // EDMA3_DRV_W8BIT = 0, // EDMA3_DRV_W16BIT = 1, // EDMA3_DRV_W32BIT = 2, // EDMA3_DRV_W64BIT = 3, // EDMA3_DRV_W128BIT = 4, // EDMA3_DRV_W256BIT = 5 uint32 TCCMODE :1; //* (Bit 11) EDMA3_DRV_OPT_FIELD_TCCMODE // EDMA3_DRV_TCCMODE_NORMAL = 0, // EDMA3_DRV_TCCMODE_EARLY = 1 uint32 TCC :6; //* (Bit 12-17) EDMA3_DRV_OPT_FIELD_TCC uint32 bit18_19:2; //* (Bit 18-19) reserved uint32 TCINTEN :1; //* (Bit 20) EDMA3_DRV_OPT_FIELD_TCINTEN // EDMA3_DRV_TCINTEN_DIS = 0, // EDMA3_DRV_TCINTEN_EN = 1 uint32 ITCINTEN:1; //* (Bit 21) EDMA3_DRV_OPT_FIELD_ITCINTEN // EDMA3_DRV_ITCINTEN_DIS = 0, // EDMA3_DRV_ITCINTEN_EN = 1 uint32 TCCHEN :1; //* (Bit 22) EDMA3_DRV_OPT_FIELD_TCCHEN // EDMA3_DRV_TCCHEN_DIS = 0, // EDMA3_DRV_TCCHEN_EN = 1 uint32 ITCCHEN :1; //* (Bit 23) EDMA3_DRV_OPT_FIELD_ITCCHEN // EDMA3_DRV_ITCCHEN_DIS = 0, // EDMA3_DRV_ITCCHEN_EN = 1 uint32 PRIVID :4; //* (Bit 24-27) EDMA3_DRV_OPT_FIELD_PRIVID (read only) uint32 bit28_30:3; //* (Bit 28-30) reserved uint32 PRIV :1; //* (Bit 31) EDMA3_DRV_OPT_FIELD_PRIV (read only) } bitfield; uint32_t u32; }EDMA_OPTIONS; extern const unsigned int numEdma3Instances; extern EDMA3_DRV_InstanceInitConfig sampleInstInitConfig[][EDMA3_MAX_REGIONS]; extern EDMA3_RM_InstanceInitConfig defInstInitConfig [][EDMA3_MAX_REGIONS]; /* External Global Configuration Structure */ extern EDMA3_DRV_GblConfigParams sampleEdma3GblCfgParams[]; EDMA3_DRV_Handle hEdma[MAX_NUM_EDMA_INSTANCES]; /* counters for debuging */ unsigned int edma_cnt = 0; unsigned int qdma1_cnt = 0; unsigned int qdma2_cnt = 0; unsigned int qdma3_cnt = 0; unsigned int qdma4_cnt = 0; static unsigned int startEdmaChainChId; static unsigned int EdmaTcc_HSdata = 0; static unsigned int QdmaTcc_Y = 0; static unsigned int QdmaTcc_X = 0; static unsigned int dmaTcc_DPRAM = 0; static unsigned int QdmaTcc_FirstHalf = 0; static unsigned int QdmaTcc_SecHalf = 0; static volatile BOOL wait_for_tcc_DPRAM; unsigned int QdmaChId_Y = 0; unsigned int QdmaChId_X = 0; unsigned int ToPPCStreamingQDMAFirstHalf = 0; unsigned int ToPPCStreamingQDMASecHalf = 0; unsigned int dmaChId_DPRAM = 0; static EDMA3_DRV_Result init_edma3_chain(EDMA3_DRV_Handle hLocEdma); static EDMA3_DRV_Result init_edma3_DPRAM(EDMA3_DRV_Handle hLocEdma); static EDMA3_DRV_Result init_qDma(EDMA3_DRV_Handle hLocEdma); EDMA3_DRV_Result edmaFail(EDMA3_DRV_Result result, int line); void DMA_TC_ISR (unsigned int tcc, EDMA3_RM_TccStatus status, void *appData); extern void ToggleDebugPortDi(uint32 Id); #if defined(_DSPBIOS) && defined(_HS_SECTIONS) #pragma CODE_SECTION(DMA_TC_ISR, ".hs") #endif void DMA_TC_ISR (unsigned int tcc, EDMA3_RM_TccStatus status, void *appData) { SBM_PROFILER_ENTERBLOCK(117); if(tcc == EdmaTcc_HSdata) { edma_cnt++; // ToggleDebugPortDi(1); PM_HighSpeedTick(); } else if(tcc == QdmaTcc_Y) { qdma1_cnt++; } else if(tcc == QdmaTcc_X) { qdma2_cnt++; } else if (tcc == QdmaTcc_FirstHalf) { qdma3_cnt++; } else if (tcc == QdmaTcc_SecHalf) { qdma4_cnt++; } else if (tcc == dmaTcc_DPRAM) { wait_for_tcc_DPRAM = FALSE; } SBM_PROFILER_LEAVEBLOCK(); } /** * \brief initialization and allocation of 3 chained EDMA channels * used for transfering HS data from FPGA to DSP * * \return EDMA3_DRV_SOK or EDMA3_DRV Error Code */ EDMA3_DRV_Result init_edma3_chain(EDMA3_DRV_Handle hLocEdma) { EDMA3_DRV_ChainOptions chain; EDMA3_DRV_Result result = EDMA3_DRV_SOK; uint16 *srcBuff; uint16 *dstBuff; unsigned int tccX = 0; unsigned int tccY = 0; unsigned int tcc1 = 0; unsigned int tcc2 = 0; unsigned int tcc3 = 0; unsigned int chXId = 0; unsigned int chYId = 0; unsigned int ch1Id = 0; unsigned int ch2Id = 0; unsigned int ch3Id = 0; // unsigned int ACnt = sizeof(Fpga_Io_Hs_Filter_Out); // unsigned int BCnt = 1; unsigned int ACnt; unsigned int BCnt; /* Setup for Channel 1 (HS_ADC) */ tccX = EDMA3_DRV_TCC_ANY; chXId = EDMA3_DRV_HW_CHANNEL_EVENT_7; /*GPINT1*/ srcBuff = (uint16*) GLOBAL_ADDR((signed char*)&(pFpga_Io_Hs_Filter_Out->channel[0])); dstBuff = (uint16*) GLOBAL_ADDR((signed char*)&(Fpga_Io_Hs_Filter_Out.channel[0])); ACnt = 8; BCnt = 4; result = edmaFail(EDMA3_DRV_requestChannel (hLocEdma, &chXId, &tccX, (EDMA3_RM_EventQueue)1, NULL, NULL) , __LINE__); result = edmaFail(EDMA3_DRV_setSrcParams (hLocEdma, chXId, (unsigned int)(srcBuff), EDMA3_DRV_ADDR_MODE_INCR, EDMA3_DRV_W16BIT) , __LINE__); result = edmaFail(EDMA3_DRV_setDestParams (hLocEdma, chXId, (unsigned int)(dstBuff), EDMA3_DRV_ADDR_MODE_INCR, EDMA3_DRV_W16BIT) , __LINE__); result = edmaFail(EDMA3_DRV_setSrcIndex (hLocEdma, chXId, 16, 0) , __LINE__); result = edmaFail(EDMA3_DRV_setDestIndex (hLocEdma, chXId, 16, 0) , __LINE__); result = edmaFail(EDMA3_DRV_setTransferParams (hLocEdma, chXId, ACnt, BCnt, 1, 1, EDMA3_DRV_SYNC_AB) , __LINE__); result = edmaFail(EDMA3_DRV_linkChannel (hLocEdma, chXId, chXId) , __LINE__); tccY = EDMA3_DRV_TCC_ANY; chYId = EDMA3_DRV_DMA_CHANNEL_ANY; //chYId = EDMA3_DRV_HW_CHANNEL_EVENT_8; /*GPINT2*/ srcBuff = (uint16*) GLOBAL_ADDR((signed char*)&(pFpga_Io_Hs_Filter_Out->channel[4])); dstBuff = (uint16*) GLOBAL_ADDR((signed char*)&(Fpga_Io_Hs_Filter_Out.channel[4])); ACnt = 8; BCnt = 4; result = edmaFail(EDMA3_DRV_requestChannel (hLocEdma, &chYId, &tccY, (EDMA3_RM_EventQueue)1, NULL, NULL) , __LINE__); result = edmaFail(EDMA3_DRV_setSrcParams (hLocEdma, chYId, (unsigned int)(srcBuff), EDMA3_DRV_ADDR_MODE_INCR, EDMA3_DRV_W16BIT) , __LINE__); result = edmaFail(EDMA3_DRV_setDestParams (hLocEdma, chYId, (unsigned int)(dstBuff), EDMA3_DRV_ADDR_MODE_INCR, EDMA3_DRV_W16BIT) , __LINE__); result = edmaFail(EDMA3_DRV_setSrcIndex (hLocEdma, chYId, 16, 0) , __LINE__); result = edmaFail(EDMA3_DRV_setDestIndex (hLocEdma, chYId, 16, 0) , __LINE__); result = edmaFail(EDMA3_DRV_setTransferParams (hLocEdma, chYId, ACnt, BCnt, 1, 1, EDMA3_DRV_SYNC_AB) , __LINE__); result = edmaFail(EDMA3_DRV_linkChannel (hLocEdma, chYId, chYId) , __LINE__); tcc1 = EDMA3_DRV_TCC_ANY; ch1Id = EDMA3_DRV_DMA_CHANNEL_ANY; srcBuff = (uint16*) GLOBAL_ADDR((signed char*)&(pFpga_Io_Hs_Filter_Out->channel[32])); dstBuff = (uint16*) GLOBAL_ADDR((signed char*)&(Fpga_Io_Hs_Filter_Out.channel[32])); ACnt = 36; /* 16 channels + counter */ BCnt = 1; result = edmaFail(EDMA3_DRV_requestChannel (hLocEdma, &ch1Id, &tcc1, (EDMA3_RM_EventQueue)1, NULL, NULL) , __LINE__); result = edmaFail(EDMA3_DRV_setSrcParams (hLocEdma, ch1Id, (unsigned int)(srcBuff), EDMA3_DRV_ADDR_MODE_INCR, EDMA3_DRV_W16BIT) , __LINE__); result = edmaFail(EDMA3_DRV_setDestParams (hLocEdma, ch1Id, (unsigned int)(dstBuff), EDMA3_DRV_ADDR_MODE_INCR, EDMA3_DRV_W16BIT) , __LINE__); result = edmaFail(EDMA3_DRV_setSrcIndex (hLocEdma, ch1Id, 0, 0) , __LINE__); result = edmaFail(EDMA3_DRV_setDestIndex (hLocEdma, ch1Id, 0, 0) , __LINE__); result = edmaFail(EDMA3_DRV_setTransferParams (hLocEdma, ch1Id, ACnt, BCnt, 1, 1, EDMA3_DRV_SYNC_A) , __LINE__); result = edmaFail(EDMA3_DRV_linkChannel (hLocEdma, ch1Id, ch1Id) , __LINE__); /* Setup for Channel 2 */ tcc2 = EDMA3_DRV_TCC_ANY; ch2Id = EDMA3_DRV_DMA_CHANNEL_ANY; srcBuff = (uint16*) GLOBAL_ADDR((signed char*)FPGA_IO_FROM_CPLD_DEFENSE_LINE); dstBuff = (uint16*) GLOBAL_ADDR((signed char*)&Fpga_Io_From_Cpld_Defense_Line); ACnt = sizeof(Fpga_Io_From_Cpld_Defense_Line); BCnt = 1; result = edmaFail(EDMA3_DRV_requestChannel (hLocEdma, &ch2Id, &tcc2, (EDMA3_RM_EventQueue)1, NULL, NULL) , __LINE__); result = edmaFail(EDMA3_DRV_setSrcParams (hLocEdma, ch2Id, (unsigned int)(srcBuff), EDMA3_DRV_ADDR_MODE_INCR, EDMA3_DRV_W16BIT) , __LINE__); result = edmaFail(EDMA3_DRV_setDestParams (hLocEdma, ch2Id, (unsigned int)(dstBuff), EDMA3_DRV_ADDR_MODE_INCR, EDMA3_DRV_W16BIT) , __LINE__); result = edmaFail(EDMA3_DRV_setSrcIndex (hLocEdma, ch2Id, 0, 0) , __LINE__); result = edmaFail(EDMA3_DRV_setDestIndex (hLocEdma, ch2Id, 0, 0) , __LINE__); result = edmaFail(EDMA3_DRV_setTransferParams (hLocEdma, ch2Id, ACnt, BCnt, 1, 1, EDMA3_DRV_SYNC_A) , __LINE__); result = edmaFail(EDMA3_DRV_linkChannel (hLocEdma, ch2Id, ch2Id) , __LINE__); /* Setup for Channel 3 */ tcc3 = EDMA3_DRV_TCC_ANY; ch3Id = EDMA3_DRV_DMA_CHANNEL_ANY; srcBuff = (uint16*) GLOBAL_ADDR((signed char*)FPGA_IO_ENCODER); dstBuff = (uint16*) GLOBAL_ADDR((signed char*)&Fpga_Io_Encoder); ACnt = sizeof(Fpga_Io_Encoder); BCnt = 1; result = edmaFail(EDMA3_DRV_requestChannel (hLocEdma, &ch3Id, &tcc3, (EDMA3_RM_EventQueue)1, &DMA_TC_ISR, NULL) , __LINE__); result = edmaFail(EDMA3_DRV_setSrcParams (hLocEdma, ch3Id, (unsigned int)(srcBuff), EDMA3_DRV_ADDR_MODE_INCR, EDMA3_DRV_W16BIT) , __LINE__); result = edmaFail(EDMA3_DRV_setDestParams (hLocEdma, ch3Id, (unsigned int)(dstBuff), EDMA3_DRV_ADDR_MODE_INCR, EDMA3_DRV_W16BIT) , __LINE__); result = edmaFail(EDMA3_DRV_setSrcIndex (hLocEdma, ch3Id, 0, 0) , __LINE__); result = edmaFail(EDMA3_DRV_setDestIndex (hLocEdma, ch3Id, 0, 0) , __LINE__); result = edmaFail(EDMA3_DRV_setTransferParams (hLocEdma, ch3Id, ACnt, BCnt, 1, 1, EDMA3_DRV_SYNC_A) , __LINE__); result = edmaFail(EDMA3_DRV_linkChannel (hLocEdma, ch3Id, ch3Id) , __LINE__); chain.tcchEn = EDMA3_DRV_TCCHEN_EN; /* Transfer complete chaining enable. */ chain.itcchEn = EDMA3_DRV_ITCCHEN_DIS; /* Intermediate transfer complete chaining disabled. */ chain.tcintEn = EDMA3_DRV_TCINTEN_DIS; /* Transfer complete interrupt is disabled. */ chain.itcintEn = EDMA3_DRV_ITCINTEN_DIS; /* Intermediate transfer complete interrupt is disabled. */ /* Now chain channel 1 and 2 together. */ result = edmaFail(EDMA3_DRV_chainChannel(hLocEdma, chXId, chYId, (EDMA3_DRV_ChainOptions *)&chain) , __LINE__); result = edmaFail(EDMA3_DRV_chainChannel(hLocEdma, chYId, ch1Id, (EDMA3_DRV_ChainOptions *)&chain) , __LINE__); /* Now chain channel 1 and 2 together. */ result = edmaFail(EDMA3_DRV_chainChannel(hLocEdma, ch1Id, ch2Id, (EDMA3_DRV_ChainOptions *)&chain) , __LINE__); chain.tcchEn = EDMA3_DRV_TCCHEN_EN; /* Transfer complete chaining enable. */ chain.itcchEn = EDMA3_DRV_ITCCHEN_DIS; /* Intermediate transfer complete chaining disabled. */ chain.tcintEn = EDMA3_DRV_TCINTEN_EN; /* Transfer complete interrupt is enabled. */ chain.itcintEn = EDMA3_DRV_ITCINTEN_DIS; /* Intermediate transfer complete interrupt is disabled. */ /* Now chain channel 2 and 3 together. */ result = edmaFail(EDMA3_DRV_chainChannel(hLocEdma, ch2Id, ch3Id, (EDMA3_DRV_ChainOptions *)&chain) , __LINE__); startEdmaChainChId = chXId; /* static channel for Chained DMA */ EdmaTcc_HSdata = tcc3; /* transfer complete code for Chained DMA transfer - used in ISR*/ return result; } EDMA3_DRV_Result init_qDma(EDMA3_DRV_Handle hLocEdma) { EDMA3_DRV_Result result = EDMA3_DRV_SOK; EDMA3_DRV_PaRAMRegs qDma_params; EDMA_OPTIONS opts; unsigned int tmpTcc = 0; unsigned int tmpChId; unsigned int tmpACnt; uint16 *srcBuff1; uint16 *dstBuff1; uint32 *srcBuff32; uint8 *srcBuff8; /************************************************************************* * setup QDMA channel for Y PWM values *************************************************************************/ srcBuff1 = (uint16*) GLOBAL_ADDR((signed char*) &(Fpga_Io_Pwm_Modulator.stYModulatorData)); dstBuff1 = (uint16*) GLOBAL_ADDR((signed char*) FPGA_IO_HS_DMA_OUT_Y); /* Setup for any QDMA Channel */ tmpChId = EDMA3_DRV_QDMA_CHANNEL_ANY; tmpTcc = EDMA3_DRV_TCC_ANY; tmpACnt = sizeof(ST_MODULATOR_DATA); if (hLocEdma != NULL ) { result = edmaFail(EDMA3_DRV_requestChannel (hLocEdma, &tmpChId, &tmpTcc, (EDMA3_RM_EventQueue)0, &DMA_TC_ISR, NULL), __LINE__); } else { result = edmaFail(EDMA3_DRV_E_INST_NOT_OPENED, __LINE__); } QdmaTcc_Y = tmpTcc; opts.bitfield.SAM = EDMA3_DRV_ADDR_MODE_INCR; opts.bitfield.DAM = EDMA3_DRV_ADDR_MODE_INCR; opts.bitfield.SYNCDIM = EDMA3_DRV_SYNC_A; opts.bitfield.STATIC = EDMA3_DRV_STATIC_EN; opts.bitfield.bit4_7 = 0; opts.bitfield.FWID = EDMA3_DRV_W16BIT; opts.bitfield.TCCMODE = EDMA3_DRV_TCCMODE_NORMAL; opts.bitfield.TCC = tmpTcc; opts.bitfield.bit18_19 = 0; opts.bitfield.TCINTEN = EDMA3_DRV_TCINTEN_DIS; opts.bitfield.ITCINTEN = EDMA3_DRV_ITCINTEN_DIS; opts.bitfield.TCCHEN = EDMA3_DRV_TCCHEN_DIS; opts.bitfield.ITCCHEN = EDMA3_DRV_ITCCHEN_DIS; opts.bitfield.bit28_30 = 0; qDma_params.opt = opts.u32; qDma_params.srcAddr = (unsigned int)srcBuff1; qDma_params.aCnt = tmpACnt; qDma_params.bCnt = 1; qDma_params.destAddr = (unsigned int)dstBuff1; qDma_params.srcBIdx = 0; qDma_params.destBIdx = 0; qDma_params.linkAddr = 0; qDma_params.bCntReload = 0; qDma_params.srcCIdx = 0; qDma_params.destCIdx = 0; qDma_params.cCnt = 1; qDma_params.reserved = 0; result = edmaFail(EDMA3_DRV_setPaRAM(hLocEdma, tmpChId, &qDma_params) , __LINE__); /* Set QDMA Trigger Word as Ccnt */ result = edmaFail(EDMA3_DRV_setQdmaTrigWord (hLocEdma, tmpChId, EDMA3_RM_QDMA_TRIG_CCNT) , __LINE__); QdmaChId_Y = tmpChId; /************************************************************************* * setup QDMA channel for X PWM values *************************************************************************/ srcBuff1 = (uint16*) GLOBAL_ADDR((signed char*) &(Fpga_Io_Pwm_Modulator.stXModulatorData)); dstBuff1 = (uint16*) GLOBAL_ADDR((signed char*) FPGA_IO_HS_DMA_OUT_X); /* Setup for any QDMA Channel */ tmpChId = EDMA3_DRV_QDMA_CHANNEL_ANY; tmpTcc = EDMA3_DRV_TCC_ANY; tmpACnt = sizeof(ST_MODULATOR_DATA); if (hLocEdma != NULL ) { result = edmaFail(EDMA3_DRV_requestChannel (hLocEdma, &tmpChId, &tmpTcc, (EDMA3_RM_EventQueue)0, &DMA_TC_ISR, NULL), __LINE__); } else { result = edmaFail(EDMA3_DRV_E_INST_NOT_OPENED, __LINE__); } QdmaTcc_X = tmpTcc; opts.bitfield.SAM = EDMA3_DRV_ADDR_MODE_INCR; opts.bitfield.DAM = EDMA3_DRV_ADDR_MODE_INCR; opts.bitfield.SYNCDIM = EDMA3_DRV_SYNC_A; opts.bitfield.STATIC = EDMA3_DRV_STATIC_EN; opts.bitfield.bit4_7 = 0; opts.bitfield.FWID = EDMA3_DRV_W16BIT; opts.bitfield.TCCMODE = EDMA3_DRV_TCCMODE_NORMAL; opts.bitfield.TCC = tmpTcc; opts.bitfield.bit18_19 = 0; opts.bitfield.TCINTEN = EDMA3_DRV_TCINTEN_DIS; opts.bitfield.ITCINTEN = EDMA3_DRV_ITCINTEN_DIS; opts.bitfield.TCCHEN = EDMA3_DRV_TCCHEN_DIS; opts.bitfield.ITCCHEN = EDMA3_DRV_ITCCHEN_DIS; opts.bitfield.bit28_30 = 0; qDma_params.opt = opts.u32; qDma_params.srcAddr = (unsigned int)srcBuff1; qDma_params.aCnt = tmpACnt; qDma_params.bCnt = 1; qDma_params.destAddr = (unsigned int)dstBuff1; qDma_params.srcBIdx = 0; qDma_params.destBIdx = 0; qDma_params.linkAddr = 0; qDma_params.bCntReload = 0; qDma_params.srcCIdx = 0; qDma_params.destCIdx = 0; qDma_params.cCnt = 1; qDma_params.reserved = 0; result = edmaFail(EDMA3_DRV_setPaRAM(hLocEdma, tmpChId, &qDma_params), __LINE__); /* Set QDMA Trigger Word as Ccnt */ result = edmaFail(EDMA3_DRV_setQdmaTrigWord (hLocEdma, tmpChId, EDMA3_RM_QDMA_TRIG_CCNT), __LINE__); QdmaChId_X = tmpChId; /************************************************************************* * setup QDMA channel for First half of streaming data * MUST configured as: (standard FIFO set up is NOT working, that why this fix) * - aCnt: 2 bytes elements per array (16bit transfer) * - bCnt: no. og arrays to be transmit per trigger * - srcBIdx: move index of StreamingBuff 2 bytes everytime a new array is transmitting * - EDMA3_DRV_SYNC_AB: transmit aCnt*bCnt elements per trigger *************************************************************************/ srcBuff32 = (uint32*) GLOBAL_ADDR((signed char*) &StreamingBuff[0]); dstBuff1 = (uint16*) GLOBAL_ADDR((signed char*) FPGA_PPC_STREAMING_FIFO_ADDR); /* Setup for any QDMA Channel */ tmpChId = EDMA3_DRV_QDMA_CHANNEL_ANY; tmpTcc = EDMA3_DRV_TCC_ANY; tmpACnt = sizeof(StreamingBuff) / sizeof(uint16)/ 2; // of only the 1. half buffer is transmitted if (hLocEdma != NULL ) { result = edmaFail(EDMA3_DRV_requestChannel (hLocEdma, &tmpChId, &tmpTcc, (EDMA3_RM_EventQueue)0, &DMA_TC_ISR, NULL), __LINE__); } else { result = edmaFail(EDMA3_DRV_E_INST_NOT_OPENED, __LINE__); } QdmaTcc_FirstHalf = tmpTcc; opts.bitfield.SAM = EDMA3_DRV_ADDR_MODE_INCR; opts.bitfield.DAM = EDMA3_DRV_ADDR_MODE_FIFO; opts.bitfield.SYNCDIM = EDMA3_DRV_SYNC_AB; opts.bitfield.STATIC = EDMA3_DRV_STATIC_EN; opts.bitfield.bit4_7 = 0; opts.bitfield.FWID = EDMA3_DRV_W16BIT; opts.bitfield.TCCMODE = EDMA3_DRV_TCCMODE_NORMAL; opts.bitfield.TCC = tmpTcc; opts.bitfield.bit18_19 = 0; opts.bitfield.TCINTEN = EDMA3_DRV_TCINTEN_DIS; opts.bitfield.ITCINTEN = EDMA3_DRV_ITCINTEN_DIS; opts.bitfield.TCCHEN = EDMA3_DRV_TCCHEN_DIS; opts.bitfield.ITCCHEN = EDMA3_DRV_ITCCHEN_DIS; opts.bitfield.bit28_30 = 0; qDma_params.opt = opts.u32; qDma_params.srcAddr = (unsigned int)srcBuff32; qDma_params.aCnt = sizeof(uint16); qDma_params.bCnt = tmpACnt; qDma_params.destAddr = (unsigned int)dstBuff1; qDma_params.srcBIdx = sizeof(uint16); qDma_params.destBIdx = 0; qDma_params.linkAddr = 0; qDma_params.bCntReload = 0; qDma_params.srcCIdx = 0; qDma_params.destCIdx = 0; qDma_params.cCnt = 1; qDma_params.reserved = 0; result = edmaFail(EDMA3_DRV_setPaRAM(hLocEdma, tmpChId, &qDma_params), __LINE__); /* Set QDMA Trigger Word as Ccnt */ result = edmaFail(EDMA3_DRV_setQdmaTrigWord (hLocEdma, tmpChId, EDMA3_RM_QDMA_TRIG_CCNT), __LINE__); ToPPCStreamingQDMAFirstHalf = tmpChId; /************************************************************************* * setup QDMA channel for Second half of streaming data * - aCnt: 2 bytes elements per array (16bit transfer) * - bCnt: no. og arrays to be transmit per trigger * - srcBIdx: move index of StreamingBuff 2 bytes everytime a new array is transmitting * - EDMA3_DRV_SYNC_AB: transmit aCnt*bCnt elements per trigger *************************************************************************/ srcBuff8 = (uint8*)StreamingBuff; // converter to byte buffer for calculation of half buffer addr. srcBuff32 = (uint32*)GLOBAL_ADDR((signed char*)(srcBuff8 + sizeof(StreamingBuff) / sizeof(uint16))); dstBuff1 = (uint16*) GLOBAL_ADDR((signed char*) FPGA_PPC_STREAMING_FIFO_ADDR); /* Setup for any QDMA Channel */ tmpChId = EDMA3_DRV_QDMA_CHANNEL_ANY; tmpTcc = EDMA3_DRV_TCC_ANY; tmpACnt = sizeof(StreamingBuff) / sizeof(uint16)/ 2; // of only the 2. half buffer is transmitting if (hLocEdma != NULL ) { result = edmaFail(EDMA3_DRV_requestChannel (hLocEdma, &tmpChId, &tmpTcc, (EDMA3_RM_EventQueue)0, &DMA_TC_ISR, NULL), __LINE__); } else { result = edmaFail(EDMA3_DRV_E_INST_NOT_OPENED, __LINE__); } QdmaTcc_SecHalf = tmpTcc; opts.bitfield.SAM = EDMA3_DRV_ADDR_MODE_INCR; opts.bitfield.DAM = EDMA3_DRV_ADDR_MODE_FIFO; opts.bitfield.SYNCDIM = EDMA3_DRV_SYNC_AB; opts.bitfield.STATIC = EDMA3_DRV_STATIC_EN; opts.bitfield.bit4_7 = 0; opts.bitfield.FWID = EDMA3_DRV_W16BIT; opts.bitfield.TCCMODE = EDMA3_DRV_TCCMODE_NORMAL; opts.bitfield.TCC = tmpTcc; opts.bitfield.bit18_19 = 0; opts.bitfield.TCINTEN = EDMA3_DRV_TCINTEN_DIS; opts.bitfield.ITCINTEN = EDMA3_DRV_ITCINTEN_DIS; opts.bitfield.TCCHEN = EDMA3_DRV_TCCHEN_DIS; opts.bitfield.ITCCHEN = EDMA3_DRV_ITCCHEN_DIS; opts.bitfield.bit28_30 = 0; qDma_params.opt = opts.u32; qDma_params.srcAddr = (unsigned int)srcBuff32; qDma_params.aCnt = sizeof(uint16); qDma_params.bCnt = tmpACnt; qDma_params.destAddr = (unsigned int)dstBuff1; qDma_params.srcBIdx = sizeof(uint16); qDma_params.destBIdx = 0; qDma_params.linkAddr = 0; qDma_params.bCntReload = 0; qDma_params.srcCIdx = 0; qDma_params.destCIdx = 0; qDma_params.cCnt = 1; qDma_params.reserved = 0; result = edmaFail(EDMA3_DRV_setPaRAM(hLocEdma, tmpChId, &qDma_params) , __LINE__); /* Set QDMA Trigger Word as Ccnt */ result = edmaFail(EDMA3_DRV_setQdmaTrigWord (hLocEdma, tmpChId, EDMA3_RM_QDMA_TRIG_CCNT) , __LINE__); ToPPCStreamingQDMASecHalf = tmpChId; return result; } /************************************************************************* * setup DMA channel for DPRAM write *************************************************************************/ EDMA3_DRV_Result init_edma3_DPRAM(EDMA3_DRV_Handle hLocEdma) { EDMA3_DRV_Result result = EDMA3_DRV_SOK; EDMA3_DRV_PaRAMRegs dma_params; EDMA_OPTIONS opts; /* Setup for any QDMA Channel */ dmaChId_DPRAM = EDMA3_DRV_DMA_CHANNEL_ANY; dmaTcc_DPRAM = EDMA3_DRV_TCC_ANY; if (hLocEdma != NULL ) { result = edmaFail(EDMA3_DRV_requestChannel (hLocEdma, &dmaChId_DPRAM, &dmaTcc_DPRAM, (EDMA3_RM_EventQueue)2, &DMA_TC_ISR, NULL), __LINE__); } else { result = edmaFail(EDMA3_DRV_E_INST_NOT_OPENED, __LINE__); } opts.bitfield.SAM = EDMA3_DRV_ADDR_MODE_INCR; opts.bitfield.DAM = EDMA3_DRV_ADDR_MODE_INCR; opts.bitfield.SYNCDIM = EDMA3_DRV_SYNC_A; opts.bitfield.STATIC = EDMA3_DRV_STATIC_EN; opts.bitfield.bit4_7 = 0; opts.bitfield.FWID = EDMA3_DRV_W16BIT; opts.bitfield.TCCMODE = EDMA3_DRV_TCCMODE_NORMAL; opts.bitfield.TCC = dmaTcc_DPRAM; opts.bitfield.bit18_19 = 0; opts.bitfield.TCINTEN = EDMA3_DRV_TCINTEN_EN; opts.bitfield.ITCINTEN = EDMA3_DRV_ITCINTEN_DIS; opts.bitfield.TCCHEN = EDMA3_DRV_TCCHEN_DIS; opts.bitfield.ITCCHEN = EDMA3_DRV_ITCCHEN_DIS; opts.bitfield.bit28_30 = 0; dma_params.opt = opts.u32; dma_params.srcAddr = 0; dma_params.aCnt = 2; dma_params.bCnt = 1; dma_params.destAddr = 0x7c004000; dma_params.srcBIdx = 1; dma_params.destBIdx = 1; dma_params.linkAddr = 0; dma_params.bCntReload = 0; dma_params.srcCIdx = 0; dma_params.destCIdx = 0; dma_params.cCnt = 1; dma_params.reserved = 0; result = edmaFail(EDMA3_DRV_setPaRAM(hLocEdma, dmaChId_DPRAM, &dma_params) , __LINE__); /* Setup for any QDMA Channel */ #if 0 result = edmaFail(EDMA3_DRV_requestChannel (hLocEdma, &dmaChId_DPRAM, &dmaTcc_DPRAM, (EDMA3_RM_EventQueue)1, NULL, NULL) , __LINE__); result = edmaFail(EDMA3_DRV_setSrcParams (hLocEdma, dmaChId_DPRAM, 0, EDMA3_DRV_ADDR_MODE_INCR, EDMA3_DRV_W16BIT) , __LINE__); result = edmaFail(EDMA3_DRV_setDestParams (hLocEdma, dmaChId_DPRAM, 0, EDMA3_DRV_ADDR_MODE_INCR, EDMA3_DRV_W16BIT) , __LINE__); result = edmaFail(EDMA3_DRV_setSrcIndex (hLocEdma, dmaChId_DPRAM, 0, 0) , __LINE__); result = edmaFail(EDMA3_DRV_setDestIndex (hLocEdma, dmaChId_DPRAM, 2, 0) , __LINE__); result = edmaFail(EDMA3_DRV_setTransferParams (hLocEdma, dmaChId_DPRAM, 1, 1, 1, 1, EDMA3_DRV_SYNC_AB) , __LINE__); result = edmaFail(EDMA3_DRV_linkChannel (hLocEdma, dmaChId_DPRAM, dmaChId_DPRAM) , __LINE__); result = edmaFail(EDMA3_DRV_setOptField (hLocEdma, dmaChId_DPRAM, EDMA3_DRV_OPT_FIELD_STATIC, EDMA3_DRV_STATIC_EN) , __LINE__); result = edmaFail(EDMA3_DRV_setOptField (hLocEdma, dmaChId_DPRAM, EDMA3_DRV_OPT_FIELD_TCCMODE, EDMA3_DRV_TCCMODE_NORMAL) , __LINE__); result = edmaFail(EDMA3_DRV_setOptField (hLocEdma, dmaChId_DPRAM, EDMA3_DRV_OPT_FIELD_TCC, dmaTcc_DPRAM) , __LINE__); result = edmaFail(EDMA3_DRV_setOptField (hLocEdma, dmaChId_DPRAM, EDMA3_DRV_OPT_FIELD_TCINTEN , EDMA3_DRV_TCINTEN_EN ) , __LINE__); result = edmaFail(EDMA3_DRV_setOptField (hLocEdma, dmaChId_DPRAM, EDMA3_DRV_OPT_FIELD_ITCINTEN, EDMA3_DRV_ITCINTEN_DIS) , __LINE__); result = edmaFail(EDMA3_DRV_setOptField (hLocEdma, dmaChId_DPRAM, EDMA3_DRV_OPT_FIELD_TCCHEN , EDMA3_DRV_TCCHEN_DIS ) , __LINE__); result = edmaFail(EDMA3_DRV_setOptField (hLocEdma, dmaChId_DPRAM, EDMA3_DRV_OPT_FIELD_ITCCHEN , EDMA3_DRV_ITCCHEN_DIS ) , __LINE__); #endif return result; } /************************* External functions ****************************/ void low_level_edma_initialize (void) { EDMA3_DRV_InstanceInitConfig *instanceConfig = NULL; EDMA3_DRV_Result edmaResult = EDMA3_DRV_SOK; memset(hEdma,0,sizeof(hEdma)); if(numEdma3Instances > MAX_NUM_EDMA_INSTANCES) { printf("Error numEdma3Instances:%d > MAX_NUM_EDMA_INSTANCES: %d\n", numEdma3Instances, MAX_NUM_EDMA_INSTANCES); return; } instanceConfig = &sampleInstInitConfig[0][0]; instanceConfig->ownDmaChannels[0] |= 1u<<7; /* assign gpio01 HW event to DMA region0 */ instanceConfig->ownPaRAMSets[0] |= 1u<<7; /* assign gpio01 HW event to DMA region0 */ instanceConfig->ownTccs[0] |= 1u<<7; /* assign gpio01 HW event to DMA region0 */ instanceConfig->ownDmaChannels[0] |= 1u<<8; /* assign gpio02 HW event to DMA region0 */ instanceConfig->ownPaRAMSets[0] |= 1u<<8; /* assign gpio02 HW event to DMA region0 */ instanceConfig->ownTccs[0] |= 1u<<8; /* assign gpio02 HW event to DMA region0 */ hEdma[0] = edma3init(0, &edmaResult); edmaFail(edmaResult, __LINE__); edmaResult = edmaFail(init_edma3_chain(hEdma[0]), __LINE__); edmaResult = edmaFail(init_qDma(hEdma[0]), __LINE__); edmaResult = edmaFail(init_edma3_DPRAM(hEdma[0]), __LINE__); //platform_write("\nDMA low level Init done!"); } EDMA3_DRV_Result enable_edma_chain(void) { EDMA3_DRV_Result result = EDMA3_DRV_SOK; if (hEdma[0]) { ///result = EDMA3_DRV_enableTransfer (hEdma[0], startEdmaChainChId, EDMA3_DRV_TRIG_MODE_MANUAL); result = EDMA3_DRV_enableTransfer (hEdma[0], startEdmaChainChId, EDMA3_DRV_TRIG_MODE_EVENT); } else { result = EDMA3_DRV_E_INST_NOT_OPENED; } return edmaFail(result, __LINE__); } EDMA3_DRV_Result trig_qDma_Y(void) { return edmaFail(EDMA3_DRV_setPaRAMEntry (hEdma[0], QdmaChId_Y, EDMA3_DRV_PARAM_ENTRY_CCNT, 1u), __LINE__); } EDMA3_DRV_Result trig_qDma_X(void) { return edmaFail(EDMA3_DRV_setPaRAMEntry (hEdma[0], QdmaChId_X, EDMA3_DRV_PARAM_ENTRY_CCNT, 1u), __LINE__); } EDMA3_DRV_Result trig_qDma_Streaming(unsigned int *chId) { return edmaFail(EDMA3_DRV_setPaRAMEntry (hEdma[0], *chId, EDMA3_DRV_PARAM_ENTRY_CCNT, 1u), __LINE__); } EDMA3_DRV_Result trig_Dma_DPRAM(volatile int16* dst, const int16* src, uint32 size) { EDMA3_DRV_Result result; result = edmaFail(EDMA3_DRV_setPaRAMEntry (hEdma[0], dmaChId_DPRAM, EDMA3_DRV_PARAM_ENTRY_SRC, (uint32_t)GLOBAL_ADDR((signed char*)src)), __LINE__); result = edmaFail(EDMA3_DRV_setPaRAMField (hEdma[0], dmaChId_DPRAM, EDMA3_DRV_PARAM_FIELD_ACNT, size*2), __LINE__); result = edmaFail(EDMA3_DRV_setPaRAMEntry (hEdma[0], dmaChId_DPRAM, EDMA3_DRV_PARAM_ENTRY_DST, (uint32_t)GLOBAL_ADDR((signed char*)dst)), __LINE__); wait_for_tcc_DPRAM = TRUE; result = EDMA3_DRV_enableTransfer (hEdma[0], dmaChId_DPRAM, EDMA3_DRV_TRIG_MODE_MANUAL); SetDebugPortDi(3); while(wait_for_tcc_DPRAM) asm(" NOP 1"); return result; } EDMA3_DRV_Result edmaFail(EDMA3_DRV_Result result, int line) { if (result != EDMA3_DRV_SOK) { platform_write("\nDMA low level init FAILS result = %d (line:%d", result, line); ERR("\nDMA low level init FAILS result = %d (line:%d", result, line); while (1); } return result; }