Hi
I’m trying to implement a DMA from the PRU data memory to ECAP0 /PWM0 in order to obtain a D/A sample transfer effect of 4 samples cyclically , continuously.
The PaRAM and the ECAP registers setup is as follows:
HWREG(EDMA3CC_EMCR)= EDMA3_SET_ALL_BITS;
HWREG(EDMA3CC_EMCRH)= EDMA3_SET_ALL_BITS;
HWREG(EDMA3CC_QEMCR)= EDMA3_SET_ALL_BITS;
//Clear the error register
HWREG(EDMA3CC_CCERRCLR)= EDMA3_SET_ALL_BITS;
//Enable DMA channel for ECAP0 event (38)
HWREG (EDMA3CC_DRAEH(0))= 0x40;
// Map the DMA channel for ECAP0 to paRAM set 0
HWREG(EDMA3CC_DCHMAP(38))= 0;
//Definition of the PaRAM set 0
HWREG(EDMA3CC_OPT(0))=0x200; //OPT=200
HWREG(EDMA3CC_SRC(0))=0x4A300000; //source is PRU0 internal data
HWREG(EDMA3CC_A_B_CNT(0))=0x40004; //ACNT=4bytes, BCNT = 4 transfers
HWREG(EDMA3CC_DST(0))=0x48300114; //destination is ecap0 cap4 reg
HWREG(EDMA3CC_SRC_DST_BIDX(0))=0x4; //byte address offset between source B arrays=4, between destination arrays is 0
HWREG(EDMA3CC_LINK_BCNTRLD(0))=0x40020; //BCNT reload 4 and link to set address 20
HWREG(EDMA3CC_SRC_DST_CIDX(0))=0x0; //byte address offset between C source arrays0, between destination arrays is 0
HWREG(EDMA3CC_CCNT(0))=0x1; //CCNT=1
// Definition of the link set 1 - address 0x20
HWREG(EDMA3CC_OPT(1))=0x200; //A synch, FIFO 32b
HWREG(EDMA3CC_SRC(1))=0x4A300000; //source is PRU0 internal data
HWREG(EDMA3CC_A_B_CNT(1))=0x40004; //ACNT=4bytes, BCNT = 4 transfers
HWREG(EDMA3CC_DST(1))=0x48300114; //destination is ecap0 cap4 reg .
HWREG(EDMA3CC_SRC_DST_BIDX(1))=0x4; //byte address offset between source B arrays=4, between destination arrays is 0
HWREG(EDMA3CC_LINK_BCNTRLD(1))=0x40020; //BCNT reload 4 and link to set address 20
HWREG(EDMA3CC_SRC_DST_CIDX(1))=0x0; //byte address offset between source arrays=0, between destination arrays is 0
HWREG(EDMA3CC_CCNT(1))=0x1; //CCNT=1
HWREG(EDMA3CC_EESRH)= 0x40; //Event ECAP0 enable set for DMA
The functions I’m using are defined in the include files of the sdk 1.0.0.6 starterware.
I made the setup of the ECAP0 registers as follows:
ECCTL2=0x290 ( PWM mode – no syncout, TSCTR free running);
CAP1=0x9c4 ( a 25us period);
ECEINT = 0x40 (Period equal as interrupt source)
As a result – the DMA is performing only and only if manually I clear the ECAP0 interrupt flag by writing in ECCLR 0x1. That means that the DMA action doesn’t clear automatically the ECAP0 interrupt flag and doesn’t enable the next DMA event even if the programmed event – Counter Equal Period happens cyclically every 25 us.
The DMA purpose being to replace time consuming ISRs I think that have to be a way to make this happen automatically.
I tried another setup using an AB transfer that had to clean the ECAP0 interrupt flag. This is described next:
HWREG(EDMA3CC_OPT(0))=0x4; //OPT=4 SYNCDIM AB synchronized
HWREG(EDMA3CC_SRC(0))=0x4A300000; //source is PRU0 internal data
HWREG(EDMA3CC_A_B_CNT(0))=0x20004; //ACNT=4bytes, BCNT = 2 transfers
HWREG(EDMA3CC_DST(0))=0x48300114; //destination is ecap0 cap4 reg and ecap0 ECCLR
HWREG(EDMA3CC_SRC_DST_BIDX(0))=0x1C0004; //byte address offset between source B arrays=4, between destination arrays is 0x1C -within a frame
HWREG(EDMA3CC_LINK_BCNTRLD(0))=0x20020; //BCNT reload 2 and link to set address 20
HWREG(EDMA3CC_SRC_DST_CIDX(0))=0x8; //byte address offset between C source arrays=8, between destination arrays is 0
HWREG(EDMA3CC_CCNT(0))=0x4; //CCNT=4
// Definition of the link set 1 - address 0x20
HWREG(EDMA3CC_OPT(1))=0x4; //OPT=4 SYNCDIM AB synchronized
HWREG(EDMA3CC_SRC(1))=0x4A300000; //source is PRU0 internal data
HWREG(EDMA3CC_A_B_CNT(1))=0x20004; //ACNT=4bytes, BCNT = 2 transfers
HWREG(EDMA3CC_DST(1))=0x48300114; //destination is ecap0 cap4 reg and ecap0 ECCLR.
HWREG(EDMA3CC_SRC_DST_BIDX(1))=0x1C0004; //byte address offset between source B arrays=4, between destination arrays is 0x1C - within a frame
HWREG(EDMA3CC_LINK_BCNTRLD(1))=0x20020; //BCNT reload 2 and link to set address 20
HWREG(EDMA3CC_SRC_DST_CIDX(1))=0x8; //byte address offset between source arrays=8, between destination arrays is 0
HWREG(EDMA3CC_CCNT(1))=0x4; //CCNT=4
HWREG(EDMA3CC_EESRH)= 0x40; //Event ECAP0 enable set for DMA
In this setup the DMA is performing – but is erratic - not in the order of the source locations – the counter is jumping.
Is there any possibility to make a setup for this type of DMA transfer? Please help.