2 Replies Latest reply on Sep 3, 2019 7:36 AM by DaJa_4418646

    PSoC6 aborting DMA and determining how much was done

    DaJa_4418646

      I've got an SCB UART connected to Rx and Tx DMA engines.

       

      I have Tx set up so that I can give it a buffer and I will get an interrupt when it's done. That works fine.

       

      I have Rx set up so that I can give it a buffer, and I will get an interrupt when the buffer is full. That also works fine.

       

      However, I would like to have some means to stop/abort the DMA on Rx and get the count of how many bytes were received so far. Ideally, I would call some function and the Rx DMA engine would finish the last iteration of what it was doing and then still call the completion ISR, but in that ISR, I can read GetXloopCount or something to determine how much had been done.

       

      I can't for the life of me get that to work. I can't figure out how to disable the DMA in such a way that I get an interrupt anyway.

       

      Alternatively, I'd be happy to skip the last interrupt and just disable the DMA, but in that case, I still want to get a count of how many bytes have transferred so far.

       

      What am I doing wrong?

       

      PS -- I'm new to PSoC so please go easy on me.

        • 1. Re: PSoC6 aborting DMA and determining how much was done
          BragadeeshV_41

          Hi DaJa_4418646,

           

          The DMA interrupt will trigger only if the DMA completes as per what is mentioned in the Interrupt descriptor.

          You can use the Tr_out signal as the input to the Count trigger signal of the counter to count the no of bytes received by the DMA channel. You can clear the counter as soon as the DMA interrupt is triggered (DMA complete event).

           

          void StopTransferReadCount()

          {

                      Cy_DMA_Channel_Disable(RxDMA_HW,RxDMA_DW_CHANNEL);

                      GetXloopCount = Cy_TCPWM_Counter_GetCounter(Counter_1_HW, Counter_1_CNT_NUM) + 1;

                      printf("\n\r%d",GetXloopCount);

                      Cy_DMA_Channel_Enable(RxDMA_HW,RxDMA_DW_CHANNEL);

          }

           

          Please note that the first count signal will be taken as start for the counter and therefore the count value is offset by 1.

           

          You can also purposefully set an interrupt using Cy_DMA_Channel_SetInterrupt(). (Not required)

           

          For example:

          void StopTransferReadCount()

               {

                     Cy_DMA_Channel_Disable(RxDMA_HW,RxDMA_DW_CHANNEL);

                     Cy_DMA_Channel_SetInterrupt(RxDMA_HW,RxDMA_DW_CHANNEL);

              }

           

          /*Rx DMA ISR*/

           

          void RxDmaCmplt(void)

          {

              /* Clears the interupt source in RxDMA channel */

              Cy_DMA_Channel_ClearInterrupt(RxDMA_HW, RxDMA_DW_CHANNEL);

              GetXloopCount = Cy_TCPWM_Counter_GetCounter(Counter_1_HW, Counter_1_CNT_NUM) + 1;

              printf("\n\r%d",GetXloopCount);

              Cy_DMA_Channel_Enable(RxDMA_HW,RxDMA_DW_CHANNEL);

          }

             

           

          Regards,

          Bragadeesh

          • 2. Re: PSoC6 aborting DMA and determining how much was done
            DaJa_4418646

            Thank you, Bragadeesh, this makes perfect sense. I'll try it out and get back to you if I have issues.

             

            Best,

            Dave J