This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DMA implementation on ECAP0/PWM

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.  

 

  • Hi,

    The eCAP module requests DMA events via its interrupt signal, rather than a separate, designated signal.  The eCAP interrupts must therefore be cleared after the DMA completes in order for subsequent DMA events to be triggered from this module.

    Regards,

    Melissa