5 Replies Latest reply on Sep 8, 2018 4:55 AM by RuPi_283656

    Multiple DMA problem


      Hello. I'm having a problem with a very simple pair of DMA channels.  Call them DMA1 and DMA2.  DMA1 was created first to write the output of an ADC channel to memory, and works fine.  Later I added DMA2 and set it up exactly the same.  However DMA2 would not work, no errors but the destination memory location always contained zero.


      I checked the setups carefully.  The channel number for DMA1 was 0 and 1 for DMA1.  The TD handle for DMA1 is 127 and 126 for DMA2.  There are no errors returned from any of the setup steps.  I eventually used the wizard to create code for the second DMA and it was identical to what I already had.  I had thought maybe the second channel needed some different values somewhere in the setup, but it appears not.  Both ADC's and DMA;s  and TD's have different names and memory locations.


      Finally in desperation I commented out all of the code for DMA1, and DMA2 started working.  Experimenting a bit I found that as long as I did not make the ADCStartConvert call for DMA1, then DMA2 works.  I tried reversing the order so that the ADCStartConvert for DMA1 is done second, but still DMA2 is the one that fails.


      So I am very unclear as to what I could be doing wrong.  I am using creator version 4.2 with a PSOC5.  Below is the setup code for both DMA's.


      Thanks for any help.



      // Defines for TempDma
      #define TempDma_BYTES_PER_BURST 2
      #define TempDma_REQUEST_PER_BURST 1
      #define TempDma_SRC_BASE (CYDEV_PERIPH_BASE)
      #define TempDma_DST_BASE (CYDEV_SRAM_BASE)


      // Variable declarations for TempDma - These are defined globally elsewhere
      // uint8 TempDma_Chan;
      // uint8 TempDma_TD[1];


      // DMA Configuration for TempDma
      TempDma_Chan = TempDma_DmaInitialize (TempDma_BYTES_PER_BURST, TempDma_REQUEST_PER_BURST,
        HI16 (TempDma_SRC_BASE), HI16 (TempDma_DST_BASE));
      TempDma_TD [0] = CyDmaTdAllocate ();
      CyDmaTdSetConfiguration (TempDma_TD [0], 2, TempDma_TD [0], TD_AUTO_EXEC_NEXT);
      CyDmaTdSetAddress (TempDma_TD [0], LO16 ((uint32) TempAdc_SAR_WRK0_PTR), LO16 ((uint32) &Td.TempResult));
      CyDmaChSetInitialTd (TempDma_Chan, TempDma_TD [0]);
      CyDmaChEnable (TempDma_Chan, 1);

      TempAdc_Start ();
      TempAdc_StartConvert ();

      // Defines for UserAttnDma
      #define UserAttnDma_BYTES_PER_BURST 2
      #define UserAttnDma_REQUEST_PER_BURST 1
      #define UserAttnDma_SRC_BASE (CYDEV_PERIPH_BASE)
      #define UserAttnDma_DST_BASE (CYDEV_SRAM_BASE)


      // Variable declarations for UserAttnDma - These are defined globally elsewhere
      // uint8 UserAttnDma_Chan;
      // uint8 UserAttnDma_TD[1];


      // DMA Configuration for TempDma
      UserAttnDma_Chan = UserAttnDma_DmaInitialize (UserAttnDma_BYTES_PER_BURST, UserAttnDma_REQUEST_PER_BURST,
        HI16 (UserAttnDma_SRC_BASE), HI16 (UserAttnDma_DST_BASE));
      UserAttnDma_TD [0] = CyDmaTdAllocate ();
      CyDmaTdSetConfiguration (UserAttnDma_TD [0], 2, UserAttnDma_TD [0], TD_AUTO_EXEC_NEXT);
      CyDmaTdSetAddress (UserAttnDma_TD [0], LO16 ((uint32) UaAdc_SAR_WRK0_PTR), LO16 ((uint32) &Td.UserAttnResult));
      CyDmaChSetInitialTd (UserAttnDma_Chan, UserAttnDma_TD [0]);
      CyDmaChEnable (UserAttnDma_Chan, 1);

      UaAdc_Start ();
      UaAdc_StartConvert ();