13 Replies Latest reply on Jun 23, 2015 8:05 PM by user_343349849

    Need help with ADC

    user_343349849

      I need to take an ADC reading at a specific point in received data stream from a wireless system.

         

      First I dropped an SAR_ADC on the project and tested it worked using this code.

         

      ADC_Start();

         

      ADC_StartConvert();

         

      result = ADC_IsEndConversion(ADC_WAIT_FOR_RESULT);

         

      RSSI_Val = ADC_GetResult16(); 

         

      Next, I set a flag at the point in data reception I wanted to start sample and when I read the flag in main code I do an ADC sample. Trouble is that I do not have control over the point a packet arrives and therfore the sampling of the ADC is not always occurring when I need it.

         

      Would someone have an example how I could start and ADC conversion within the Uart Interrupt routine so that when I get back in main loop the conversion would have been doen at the right time and I can read the value at that point?

         

       

         

      Thanks

        • 1. Re: Need help with ADC
          user_14586677

          One way of doing it is run SAR continuously, oversampled, and

             

          DMA the result to a memory location. Then use packet received flag

             

          to simply 'pick" up the result in the memory location.

             

           

             

          Or in packet received start adc, wait for its conversion complete. Would the

             

          SAR be fast enough to meet your needs ?

             

           

             

          How much latency can you tolerate from packet received to ADC result ?

             

           

             

          Regards, Dana.

          • 2. Re: Need help with ADC
            user_342122993

            @Orbitcom,

               

            The problem might not be in fast handling of the UART message, but because UART is non-deterministic itself. UART has latency, which can be ~0.1sec. For example you are sending in equal intervals "ADC_start",..."ADC_start",..."ADC_start",... but those packets will not arrive at same intervals, there will be some jitter from packet to packet. Even if ADC sampling starts immediately upon packet received, there will be some time jitter relative to the original 'sent' packet.

               

            You need some hard reference to sync ADC sampling. Look at GPS: it has precise global clock TTL each second alongside to slow UART NEMA output.

               

            odissey1

            • 3. Re: Need help with ADC
              user_343349849

               Dana,

                 

              The idea of running the ADC continuously and storing to memory location via DMA sounds like a reasonable approach. 

                 

              I have not used DMA before, is it easy to set up? Also, could I simply copy the register the values are being stored into my variable at the point required inside the Uart interrupt?

                 

              If si, I could actually save an array of values (one at each received byte) and obtain and average for the entire message.

                 

              The incoming data rate is 38k Baud. The packets are small (14 bytes fixed length). They arrive at pseudo random intervals with 3-5 packets per second.

                 

              thanks

              • 4. Re: Need help with ADC
                user_14586677

                I have not used DMA before, is it easy to set up?

                   

                 

                   

                Yes, there is a wizard in Creator for setup and some good ap notes (Creator also has a number of example projects) -

                   

                 

                   

                    

                   

                         

                   

                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)

                   

                 

                   

                 

                   

                Also, could I simply copy the register the values are being stored into my variable at the point required inside the Uart interrupt?

                   

                 

                   

                Yes. You can even have the DMA run a loop where you auto inc the address where bytes are

                   

                going. You supply a pointer to DMA config for this purpose and an inc value in # bytes depending

                   

                on what you are transferring. At end of DMA trigger an interrupt and do the average.

                   

                 

                   

                Regards, Dana.

                • 5. Re: Need help with ADC
                  user_343349849

                   I set up the DMA using the Wizard but do not appear to be getting ADC results int my memory location.

                     

                  The code generated by the wizard is shown below...

                     

                  The ADC -> EOC is connected to DMA -> DRQ, the hardware request is "derived" (I also tried rising edge).

                     

                  RSSI_Val does not appear to be updated with ADC value.

                     

                  DMA_Chan = DMA_DmaInitialize(DMA_BYTES_PER_BURST, DMA_REQUEST_PER_BURST, HI16(DMA_SRC_BASE), HI16(DMA_DST_BASE));

                     

                  DMA_TD[0] = CyDmaTdAllocate();

                     

                  CyDmaTdSetConfiguration(DMA_TD[0], 2, DMA_TD[0], TD_INC_DST_ADR | TD_AUTO_EXEC_NEXT);

                     

                  CyDmaTdSetAddress(DMA_TD[0], LO16((uint32)ADC_SAR_WRK0_PTR), LO16((uint32)RSSI_Val));

                     

                  CyDmaChSetInitialTd(DMA_Chan, DMA_TD[0]);

                     

                  CyDmaChEnable(DMA_Chan, 1);

                  • 6. Re: Need help with ADC
                    user_343349849

                     Still cannot get my DMA running for some reason.

                       

                    By the way, what controls conflict when I attempt to read the memory location the DMA is putting data?

                    • 7. Re: Need help with ADC
                      user_343349849

                       Still cannot get my DMA running for some reason.

                         

                      By the way, what controls conflict when I attempt to read the memory location the DMA is putting data?

                      • 8. Re: Need help with ADC
                        user_1377889

                        Who told you to use "AUTO_EXEC_NEXT"?

                           

                        This will not wait for ADC data ready.

                           

                         

                           

                        Bob

                        • 9. Re: Need help with ADC
                          user_343349849

                           It was the wonderful wizard of oz. (DMA Wizard configuration starting from page 21 of Doc no. 001-52705 rev 1. Self described as easy to set up the firmware configuration (ideal for a DMA newbie).

                             

                          I followed the documented example but set Auto Next to true and Next TD = 0 (to go back and rerun).

                             

                          What did I miss here?

                          • 10. Re: Need help with ADC
                            user_343349849

                             I have a SAR ADC connected to my Analog input pin. The mode is set to free running.

                               

                            The EOC is connected to the "drq" pin of the DMA. The DMA hardware request set to Derived. Then used the wizard again and set number of TD = 1 and select "Loop".

                               

                            I start the ADC in code and also have used code below. The RSSI_Val remains at "0". If I remove the DMA and do a manual sample using ADC API I get the correct values.

                               

                            /* Variable declarations for DMA */

                               

                            /* Move these variable declarations to the top of the function */

                               

                            uint8 DMA_Chan;

                               

                            uint8 DMA_TD[1];

                               

                             

                               

                            /* DMA Configuration for DMA */

                               

                            #define DMA_BYTES_PER_BURST 2

                               

                            #define DMA_REQUEST_PER_BURST 1

                               

                            #define DMA_SRC_BASE (CYDEV_PERIPH_BASE)

                               

                            #define DMA_DST_BASE (CYDEV_SRAM_BASE)

                               
                                DMA_Chan = DMA_DmaInitialize(DMA_BYTES_PER_BURST, DMA_REQUEST_PER_BURST, HI16(DMA_SRC_BASE), HI16(DMA_DST_BASE));   
                               

                            DMA_TD[0] = CyDmaTdAllocate();

                               

                            CyDmaTdSetConfiguration(DMA_TD[0], 2, DMA_TD[0], 0);

                               

                             CyDmaTdSetAddress(DMA_TD[0], LO16((uint32)ADC_SAR_WRK0_PTR), LO16((uint32)RSSI_Val));

                               

                             CyDmaChSetInitialTd(DMA_Chan, DMA_TD[0]);

                               

                             CyDmaChEnable(DMA_Chan, 1);

                            • 11. Re: Need help with ADC
                              user_1377889

                              It would be much easier for me to get hands on your (not-)working project, so I could adapt it to my hardware (-050 board) and test it.

                                 

                              Can you just reduce your project to the barest and upload it?

                                 

                               

                                 

                              Bob

                              • 12. Re: Need help with ADC
                                user_343349849

                                 Bob,

                                   

                                Cut down project attached.This locks up in main loop.

                                   

                                What I need is the ADC obtaining data continuously and poking result via DMA into the "signal Level" variable.

                                   

                                The aim is to capture the level sample as close to the specific time in my code possible.

                                • 13. Re: Need help with ADC
                                  user_343349849

                                   Attachment cause gobbly gook on screen and didn't upload for some reason. Here is second attempt to upload it.