1 2 Previous Next 16 Replies Latest reply on Dec 22, 2014 8:40 PM by user_302397898

    MUX to SAR to DMA two arrays


       Using the CYC8KIT-050, I am trying to multiplex two analog inputs to a ADC_SAR and have the two channels' input samples go to separate arrays. Disclosure: I have had a case open on this for two weeks but the only response I got was a lame example of a single analog input pin sending 200 samples to Array1 and then 200 samples to Array2 using two TDs.  That's not what I need to do.  I need one sample from input A, then a sample from input B ... repeat until 2040 samples are collected in each array ( DMA_A[2040] and DMA_B[2040] ). Later I need to time align the samples in a FIR Filter (not shown in this simplified version). My problem is that I seem to only write to the first element of each array -- at best.


      In the TopDesign I am using a LUT to select the MUX input. I'm using a countdown timer to generate an Interrupt when we have 4080 samples collected.  Each EOC ticks down the timer and generates a new SOC delayed by 1.5us through the PWM. I'm using two TDs, one for each array.


      In the project attached, the DMA_Done ISR serves no purpose. In another version, I sent one sample to a single variable using one TD, then used the ISR to load it into either DMA_A or DMA_B. I checked to see if our sample count was even or odd to determine which array to load like this:


      CY_ISR(DMA_Done)  // interrupt handler for DMA done
         if (adc_count & 1)   //  See if the array offset is even or odd
             DMA_B[adc_count] = adc_read;  // it's odd -- Load Right Channel
             DMA_A[adc_count] = adc_read;  // it's even -- Load Left Channel

              adc_count++;  // adc_count is declared as volatile
              DMA_Done_flag = 1;


      In the while (forever) loop, I print the values of DMA_A elements 1,2,and 3 on the top row of the LCD. I  print DMA_B elements 1,2,3 on the sencond row. NOTE: To test this you must assure that at least one channel's input connection to the potentiometer on P3[6] in the cydwr. Note that the dummy initalizations in lines 169,170 do not get overwritten by data as shown on the LCD.


      If this method is not feasible, perhaps someone could suggest a C++ structure that could separate every other element from a single array without using CPU cycles in a for loop. The single starting array would be:


      But my FIR Filter will have to see:
      sampleA[1],sampleA[2],sampleA[3]... in channel A, and
      sampleB[1],sampleB[2],sampleB[3]... in channel B


      Workspace Bundle attached. Thank you.

        • 1. Re: MUX to SAR to DMA two arrays

          Looking just at the code you posted: for each array, you only write to every second element (0, 2, 4 for DMA_A, and 1, 3, 5 for DMA_B).


          Using the DMA; what you need is called 'scatter-gather DMA' (and is explained under that name in the TRM). What you do is:

          • create two TDs for your DMA, each pointing to the corresponding array
          • link them in a loop, so they are executed after each other
          • transfer count is 2040 for each, and set the
          • 'request per burst' is set to 1, so only single bytes are transferred each time
          • maybe you want to set 'preserve TDs' so the DMA can start over after filling the buffer
          • you need to set 'increment destination address' on both TDs

          There is an example doing nearly what you need, but without the memory (it just sends data from the three channels to three DACs): http://www.cypress.com/?id=4&rID=60629

          • 2. Re: MUX to SAR to DMA two arrays

             Additional info: While this didn't solve my problem, I just noticed an error source in my code in my previous post. Instead of saying: if(adc_count & 1) ... I should have said: if(1 && adc_count)...  The former would do an assignment while the latter does a compare and catches such a possible error.  Still working on the problem, though.

            • 3. Re: MUX to SAR to DMA two arrays

               Thanks, hli, My previous post was about my own comment, not yours.


              That example might prove to be helpful for hardware parameters. I'm looking at it now. Actually, Request per Burst = 1 means True, not the number of bytes and it is set to 1 in my code.  My samples are 12 bits (2 bytes).  I have tried several permutations of 


              CyDmaTdSetConfiguration(DMA_1_TD[0], 2, DMA_1_TD[1], TD_INC_DST_ADR | TD_AUTO_EXEC_NEXT);
              CyDmaTdSetConfiguration(DMA_1_TD[1], 2, DMA_1_TD[0], DMA_1__TD_TERMOUT_EN | TD_INC_DST_ADR |   TD_AUTO_EXEC_NEXT);
              CyDmaTdSetAddress(DMA_1_TD[0], LO16((uint32)ADC_SAR_SAR_WRK0_PTR), LO16((uint32)DMA_A));
              CyDmaTdSetAddress(DMA_1_TD[1], LO16((uint32)ADC_SAR_SAR_WRK0_PTR), LO16((uint32)DMA_B));


              How does one specify "Preserve TDs?"
              I'll keep experimenting. Meanwhile any further tips are highly welcome as I still don't have it working.

              • 4. Re: MUX to SAR to DMA two arrays

                Just to be sure you have seen these ? -








                http://www.cypress.com/?rID=37793     AN52705     Getting Started with DMA


                http://www.cypress.com/?rID=82680     AN84810     PSoC® 3 and PSoC 5LP Advanced DMA Topics


                http://www.cypress.com/?rID=44335     AN61102 PSoC® 3 and PSoC 5LP - ADC Data Buffering Using DMA


                http://video.cypress.com/video-library/search/dma/     Videos on DMA


                https://www.youtube.com/results?search_query=dma+psoc Videos on DMA (some overlap)




                The dual array approach certainly you should be able to get working, but why not one


                array, then odd address would be one channel, even the other. Would that also fix your


                time aligned problem in filtering ? Additionally use a D or T clocked by EOC to drive the mux


                channel selection as a simplification ? As far as delay for mux settling, your conversion rate


                pretty low for SAR, why not double conversion rate and throw every other sample away ? Just


                a thought.




                Regards, Dana.

                • 5. Re: MUX to SAR to DMA two arrays

                  If you want to make the code totally clear, you should actually use


                  if (1==(1 & adcCount))


                  . '&' does bit-manipulation (so it gets you the lowest bit of the value), while '&&' does logical conditions (meaning it treats both the 1 and adcValue as boolean values and the AND-connects them - which is not what you want.

                  1 of 1 people found this helpful
                  • 6. Re: MUX to SAR to DMA two arrays

                    I know that 'request per burst==1' means true, and thats what I intended.


                    If you want to transfer 2 bytes per burst, ou need to specify that ('bytes per burst'). Look at AN61102 for an example how to do that with a single channel. Maybe its better to start with a single channel first in your case and get that working. That way you know that at least that part works.


                    Btw: is there a reason not two use two SAR ADCs? That way you could easily parallelize the DMAs. (Actually, thats even doable with a single ADC: set up two DMAs with the proper configuration, and ping-pong the DMA request between them)

                    • 7. Re: MUX to SAR to DMA two arrays

                       @hli, Those are good ideas. Your if logic suggestion is well taken. It looks like I will need to go to two DMAs. I am not sure how to ping pong each new sample selecting either this dma or that dma. I'm studying on that.  One 2-byte sample from MUX input 1 going to DMA1 and the next 2-byte sample from input 2 going to DMA2 and repeat.


                      @danaknight, I had seen most of those ANs but the reading the second one again gave me the idea of connecting the Timer's comp output to the DMA trq to terminate the session. I'm not sure how to configure hardware to select every other sample of an array. Perhaps that's related to my comment in the previous paragraph.  Is this done with TDs? Do I create two Channels on a DMA or one channel on two DMAs?

                      • 8. Re: MUX to SAR to DMA two arrays

                        This shows an interesting approach using an intermediate register,


                        not sure if it would serve your case but interesting.








                        https://www.youtube.com/watch?v=_WReMrxEBCs     20 bit ADC DMA






                        Regards, Dana.

                        • 9. Re: MUX to SAR to DMA two arrays

                          To ping-pong between the two MUX inputs and the two DMAs, just use a LUT to enable the state logic.

                          • 10. Re: MUX to SAR to DMA two arrays

                            I have not tried this but seems like it should work pretty straight forward -


                            Note I did not connect trq's to anything, you could use them to end DMA


                            activity so you would connect to Tc out on the counter, both trq's.





                            • 11. Re: MUX to SAR to DMA two arrays

                               Thanks to you guys! I feel like I'm sitting at the feet of Socrates. You make the right comments to lead me to my own exploration.


                              Danaaknight, I love that diagram.  The logic gates are perfectly suited to my purpose -- and I haven't even tried it yet. Why didn't I think of that?  This could eliminate my Sequencing Logic.  The only reason I put in the PWM is that one of the Example Projects suggested that it is necessary to let the MUX settle.  But let's remove it to simplify.  If so, I'll add it back in.  Fantastic -- simple logic gates.  I'll let you know after I try it. Stay tuned.

                              • 12. Re: MUX to SAR to DMA two arrays

                                The reason this works is the eos output allows us to switch the mux


                                to the next channel while the SAR is converting, it is cool for that


                                reason. I was not aware of this control until I looked at SAR config.


                                Although one shortcoming is no AC specs for this output in datasheet.


                                But I think if you use a scope and look at eos and eoc, difference will


                                be settling time new channel experiences, if its << uS range all


                                should be good. 20 pF and 1 K R-C spurs will settle in 8.3 time


                                constants in a 12 bit system. Thats ~ 160 nS. See -










                                Socrates no, we all learn from the customer base quite often.




                                Regards, Dana.

                                • 13. Re: MUX to SAR to DMA two arrays

                                  I had to make 2 changes, mux mode to mux which then required the clock,


                                  and counter from fixed to UDB because fixed clock input limitations. This


                                  compiles w/o error. There is a warning which I do not think is an issue


                                  that effects operation.




                                  I also connected the trq's to force a DMA terminate, although I think thats


                                  redundant because TD will have termination parameters. You can try with/






                                  Regards, Dana.





                                  • 14. Re: MUX to SAR to DMA two arrays

                                     It seems to be working. Thanks to all who helped.

                                    1 2 Previous Next