6 Replies Latest reply on May 16, 2011 5:23 AM by udayan.umapathi

    Problem with PSOC5 DMA

    user_89283927

      I'm using PSOC5 and I need to configure an DMA channel to tranfer 16 bit data from a memory table (1024 words) to the compare register in a PWM (16 bit) module. I need to make the transference only once, generate an interruption to advise about the end of the transfer and wait for the next transfer when it is needed.

         

      My problem is that after the transfer the DMA generates the interrupt but doesn't stop and seems to repeat the transfer of the same block for ever

         

      All the examples I've found about the DMA work in a repetitive way, not in one shot as I need. Nevertheless I configured the DMA as follows:

         

       

         

      /* DMA Configuration for DMA_PWM */

             

      #define

         

       

         

      DMA_PWM_BYTES_PER_BURST 2

         

      #define

              DMA_PWM_REQUEST_PER_BURST 1   

      #define

          DMA_PWM_SRC_BASE (CYDEV_FLASH_BASE)   

      #define

          DMA_PWM_DST_BASE (CYDEV_PERIPH_BASE)   

      DMA_PWM_Chan = DMA_PWM_DmaInitialize(DMA_PWM_BYTES_PER_BURST, DMA_PWM_REQUEST_PER_BURST,

       

       

      HI16(DMA_PWM_SRC_BASE), HI16(DMA_PWM_DST_BASE));

       

       

       

       

       

       

      DMA_PWM_TD[0] = CyDmaTdAllocate();

      CyDmaTdSetConfiguration(DMA_PWM_TD[0], 2048, DMA_INVALID_TD, DMA_PWM__TD_TERMOUT_EN | TD_INC_SRC_ADR);

      CyDmaTdSetAddress(DMA_PWM_TD[0], LO16((

      uint32)buffer_pwm), LO16((uint32)PWM_1_COMPARE1_LSB_PTR));

      CyDmaChSetInitialTd(DMA_PWM_Chan, DMA_PWM_TD[0]);

      CyDmaChEnable(DMA_PWM_Chan, 1);

       

       

        • 1. Re: Problem with PSOC5 DMA
          user_78878863

          Do you want to transfer all 1024 values in one shot, or each value on request? AFAICS you set the DMA to transfer 2 bytes with each request - how have you wired up the DMA component to generate the burst request? The interrupt should be executed after all 1024 values have been transferred - and the configuration is set to end the DMA then.

          • 2. Re: Problem with PSOC5 DMA
            user_89283927

            I've connected the drq of DMA to the TC output of a timer, the idea is to transfer 16 bits (2 bytes) each timer period and stop after 1024 tranfer.

            • 3. Re: Problem with PSOC5 DMA
              user_78878863

              I think your code should do what you want - don't know why it doesn't work. One thing you could do is to enable the termination output of the DMA, and use it to stop the timer. That way you don't depend on the exact configuration of the DMA.

              • 4. Re: Problem with PSOC5 DMA
                udayan.umapathi

                Could you replace the DMA_INVALID_TD parameter with a value 0xFE and try .

                • 5. Re: Problem with PSOC5 DMA
                  user_89283927

                  I've tryed the value oxFE but I'm getting only one interruption, after that "CyDmaChEnable(DMA_PWM_Chan, 1);" has no effect.

                     

                  In the mean time I'm using my configuration, then I make "CyDmaChDisable(DMA_PWM_Chan);" in the DMA interruption routine, this stops the DMA. This is nos actually a problem because I have some time between two DMA access, then, when I need again, I call "CyDmaChEnable".

                  • 6. Re: Problem with PSOC5 DMA
                    udayan.umapathi
                          
                    • PSoC5 ES1 has a silicon bug wherein the DMA chain would not terminate when the next_TD parameter is set to DMA_INVALID_TD.  This will be fixed in next revision of Silicon.
                    •    
                       

                     

                       
                          
                    • WorkAround: The TD chain termination can be hence achieved by using another TD chained to the original TD. This TD needs to have destination address  DMAC_TDMEM[tdHandle].TD0[2]. The source address should be an SRAM location where the value  0xFF is stored, it could just be an 8 bit variable. Note that the tdHandle parameter above will be the value that was obtained eariler using CyDmaTdAllocate() API.
                    •    
                       

                    Let us know if this works.