Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: Timing for running two DMA channels sequentially

  1. #1
    Junior Member
    Join Date
    Jan 2018
    Posts
    15

    Timing for running two DMA channels sequentially

    Hi all,

    I have a very similar issue to the one presented here, where when we set up two DMAChannel objects triggering off the PDB (on the 3.6), we encounter a timing issue that one channel appears to run at double speed. The fix in that thread was to run the second DMA channel by triggering off transfers of the first. However, I'd like to have one DMA channel run and make its transfers to a destination, then stop. At this point, the second channel begins, making its transfers (to that same destination), then stopping as well. The completion of each channel triggers the other to begin again, and so they alternate back and forth continually.

    Because the two channels never run simultaneously, I can't trigger off of the transfers occurring in one of them.

    Any suggestions?

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,529
    The DMA channels have an ability to automatically load new settings upon completion. Maybe that can help?

  3. #3
    Junior Member
    Join Date
    Jan 2018
    Posts
    15
    Oh cool, I had seen that in the source code for the library but not understood what it meant. Here's the relevant part of what I did:

    Code:
    void setup() {
      DMAChannel dma0(false);
    
      DMASetting dma1;
      DMASetting dma2;
    
      dma0.begin(true);
      dma0.triggerAtHardwareEvent(DMAMUX_SOURCE_PDB);
      
      dma1.sourceBuffer(table1, sizeof(table1));
      dma1.destination(*(volatile uint16_t *)&(DAC1_DAT0L));
      dma1.interruptAtCompletion();
      dma1.replaceSettingsOnCompletion(dma2);
    
      dma2.sourceBuffer(table2, sizeof(table2));
      dma2.destination(*(volatile uint16_t *)&(DAC1_DAT0L));
      dma2.interruptAtCompletion();
      dma2.replaceSettingsOnCompletion(dma1);
    
      dma0 = dma1;
      dma0.enable();
      dma0.attachInterrupt(dma_isr);
    }
    
    void dma_isr() {
      // do stuff
      dma0.clearInterrupt();
    }
    where the table1 and table2 are defined elsewhere, and I use the ISR to raise flags to start other functions in the script. Seems to be working fine!

    Thanks Paul

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •