Settings to be given to make a single channel SAR ADC operate at 1Msps

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

 Hi All,

   

I am not sure if all of you are aware of this. You need to configure Vref to "Internal 1.024 V bypassed" from the drop-down list in SAR ADC to obtain 1Msps of conversion rate. Also averaging option has to be disabled.

   

One important point to be noted is that to obtain exact 1Msps sampling rate, the IMO should be configured to be 36 MHz.

   

Regards,

   

Asha

0 Likes
45 Replies
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

At least on the PSoC5LP, there is a bug preventing the use of the maximum sample rate: when configuring the ADC clock to 18MHz, Creator complains that the clock together with its accuracy range is outside of the allowed range (its 18MHz+-0.01%, which is higher than the allowed 18MHz).

   

Does this problem exist also with the PSoC4 implementation (meaning: did you try this)?

0 Likes
Anonymous
Not applicable
        Hi, Yes, it is perfectly working for me and I didn't get any such warning in PSoC 4. Are you facing any problem in implementing this in PSoC 4? Regards, Asha   
0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Setting IMO to 36 Mhz, I was able to get SAR to compile with 18 Mhz clock.

   

 

   

Hli is referrinjg, I think, to a problem forum found in PSOC 5 that Cypress

   

is aware of to be fixed in future release.

   

 

   

Regards, Dana.

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

Its not a problem in the PSoC5 silicon. This problem is due to the way the SAR ADC component in creator handles the verification of the frequency settings (one can look up the sources, it handles the boundaries wrong in this case). Since the SAR ADC component for the PsoC4 is a different one, I was hoping this problem had been fixed there (and it seems it is).

   

So for the PSoC5 a new Creator version should help here...

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Cypress has already acknowleged a fix in future Creator release,

   

to fix PSOC 5 clock tool margin examination.

   

 

   

Regards, Dana.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

@HLI,

   

probably it was the same guy that programmed the SAR/ADC clocks making the same mistake again...

   

That's human!

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Hi everybody, I'm having some issues using ADC from PSOC 4, I got configure it in 1Msps, but when I test it, It works only in 340kbps.
Somebody can help me.
See my code.

I'm sampling 400 samples and latter on I send by UART.

   

 

   

#include <project.h>
#include <stdio.h>

int main()
{
    /* Place your initialization/startup code here (e.g. MyInst_Start()) */
    PWM_1_Start();
    Clock_Start();
    ADC_Start();
    ADC_StartConvert();
    UART_Start();
   
   
    char8 a[32];
    int i=0;
    int buffer[400];
   
    /* CyGlobalIntEnable; */ /* Uncomment this line to enable global interrupts. */
    for(;;)
    {
        if(ADC_IsEndConversion(ADC_RETURN_STATUS))
        {
           
            for (i=0; i<=400; i++)
            {
            buffer= ADC_GetResult16(0);  
             }
            for (i=0; i<=400; i++)
            {
            sprintf(a, "%i" ,buffer);
            UART_UartPutString(a);
            UART_UartPutString("\n");
             }
           
        }
    }
}

/* [] END OF FILE */

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

As in most cases the error may be hidden in some of your settings, so better will be to upload your complete project with all of the settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.

You read from ADC without checking for every result if a value is ready. There is a parameter which will wait until a conversion is done.

   



Bob

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Right now after the first conversion occurs you

   

fill the entire buffer with that sample.

   

 

   

Note the test for sample ready can be blocking or non blocking, see

   

below.

   

 

   

Regards, Dana.

   

 

   

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

How did you measure the sample rate? It probably takes longer to transfer 400 samples via UART than to sample them at 1Msps... And Bob is right - you just read the ADC results but check only once - so you will finish with the 400 samples even before the 400µs are elapsed.

   

Or your MCU core is clocked too slow, then your reading will take longer than 1µs per sample, making it apear as if the sampling is too slow. For such high sample rather its better to use DMA.

   

Btw: when you encounter a new problem, its better to open a new thread than to re-open an existing one.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

No DMA in PSOC 4.

0 Likes
lock attach
Attachments are accessible only for community members.
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Have a look at this example (sorry for the mismatching name)

   

 

   

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Thank you, for reply my question.

So first. How I measure the sample rate. I 'm generating a square wave with PWM, so I know the exact period of the signal. Then I divided the period by the number of the samples.

I'm attaching the project. And I'd like to know if there is difference between run PSOC in 3.3V or 5V. Difference in ADC speed.

0 Likes
Anonymous
Not applicable

I tried without this line:

if(ADC_IsEndConversion(ADC_RETURN_STATUS))

But the speed is the same.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

So first. How I measure the sample rate. I 'm generating a square wave with PWM, so I know the exact period of the signal. Then I divided the period by the number of the samples.

   

 

   

For 12 bits SAR takes 18 clocks, so if sample rate is 500 Ksps then Clk would have to be 9 Mhz.

   

Note you would select external clock and feed your external clock to the SAR clcok pin. Right

   

now you are set to internal clock, so PWM clock gen irrelevant, unless you are using for some-

   

thing else.

   



I'm attaching the project. And I'd like to know if there is difference between run PSOC in 3.3V or 5V.

   

Difference in ADC speed.

   

 

   

Datasheet not real clear on this, but does infer AC specs are for Vdd 1.71 to 5.5 over temp.

   

Device Level Specifications
All specifications are valid for -40 °C TA 85 °C and TJ 100 °C, except where noted. Specifications are valid for 1.71 V to 5.5 V,
except where noted.

   

 

   

Regards, Dana.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

This code still gets the first sample correctly, then w/o checking for

   

succeedding samples if SAR is finished grabs garbage off the SAR

   

to fill the array. You have to move the IsEndConversion test inside

   

the 2'ond for loop, the one that is filling the array, so each sample is

   

loaded after SAR indicates it is finished with the current sample.

   

 

   

    for(;;)

   

    {
        if(ADC_IsEndConversion(ADC_RETURN_STATUS))
        {
           
            for (i=0; i<=400; i++)
            {
            buffer= ADC_GetResult16(0);  
             }
            for (i=0; i<=400; i++)
            {
            sprintf(a, "%i" ,buffer);
            UART_UartPutString(a);
            UART_UartPutString("\n");
             }
           
        }
    }

   

 

   

Regards, Dana.

0 Likes
Anonymous
Not applicable

Like this Dana?

   

for (i=0; i<=400; i++)
            {
           
            buffer= ADC_GetResult16(0);  
             }

   

           ADC_IsEndConversion(ADC_WAIT_FOR_RESULT);
            for (i=0; i<=400; i++)
            {
            sprintf(a, "%i" ,buffer);
            UART_UartPutString(a);
            UART_UartPutString("\n");

   

            }

0 Likes
Anonymous
Not applicable

Someone could show me exactly Where I have to put the capacitor when I 'm using "Internal 1.024V, bypassed". I'd like to see a sketch.
Thank you very much everybody.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Datasheet of ADC-SAR page 5 shows pin1[7] for bypass cap.

   

 

   

Bob

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Like this -

   

 

   

    for( ; ; ) {
           
        for ( i = 0; i < 400; i++ ) {                                                                 // Log 400 samples

            ADC_IsEndConversion( ADC_WAIT_FOR_RESULT );             // Wait for each sample to complete
            buffer= ADC_GetResult16( 0 );  
         }
       
        for ( i = 0; i < 400; i++ ) {
           
            sprintf( a, "%i" ,buffer[ i ] );
            UART_UartPutString( a );
            UART_UartPutString( "\n" );
         }
    }
 

   

 

   

Regards, Dana.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

For best performance use both a .01 Ceramic and for bulk use a polymer tanalum.

   

 

   

0 Likes
Anonymous
Not applicable

This way the sample rate fall to 220ksps, without this line the sample rate is 350ksps.

0 Likes
Anonymous
Not applicable

Dana

   

My doubt is:
I have to put the capacitor between the pin 1.7 and the GND
or
Pin 1.7 and the input of the analog signal, for example in my project to the ADC input pin is 2.0.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

It is named "Bypass", so it is connected to pin and GND as I understand.

   

 

   

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Thank you everybody for everything, but i'm giving up. I tried a lot of changes but the maximum sample rate that I got it was 350Ksps.
See my test on execel.
 

   

As I told you I'm trying to sample 1 sample each 1us, my analog input has 10Khz so I need 100 samples per period and
in my testing I had only 35 or 36 at most.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

So please post your project so that we can have a look at *all* of your settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.



Bob
 

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Here it is Bob, take a look please.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

I set this up on a Pioneer board, IMO 36 Mhz, SAR clk 18 Mhz,

   

and by flipping a pin measured 2.36 mS for the 500 samples

   

to fill the array.

   

 

   

So I moved pin flipping inside loop to just measure storage into array,

   

thats taking 2.31 uS. So 2.31 uS x 500 samples = 1.15 mS. So its taking

   

1.15 mS to get SAR data and move it into array. Sure looks like DMA solution

   

will be the best bet.. Uh-oh, just remembered, no DMA in PSOC 4.

   

 

   

Note, in coding, if you define an array of 500, its address ranges from 0 - 499.

   

In your code your for loop fin test is <= 500 which means you will write to a non

   

existent array element, namely address 500 and then exit loop on 501. Test

   

should just be <

   

 

   

Regards, Dana.

0 Likes
lock attach
Attachments are accessible only for community members.
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

I tightened the loop which collects the ADC-samples. Could not run because currently no access to my lab.

   

Before you compile: change the dependencies of the BootLoader so it is using your files, not mine.

   

Insert Dana's suggestion with the pin-flip, will help you to measure time.

   

After first test, change the configuration from "Debug" to "Release" whicch will free some more MIPS.

   

 

   

Bob

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

I tired this also on a PSOC 5LP, basically same results. I am

   

going to file a CASE today to "unravel" this problem, see what

   

Cypress says.

   

 

   

Regards, Dana.

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Thank very much Bob and Dana. With the help of Bob now I'm getting 61 samples in 100us (approximately 600 Ksps), see my file attached.
I didn't understand yet this two lines in the code, but i'm happy with the results.

ADC_SAR_INTR_REG = ADC_EOS_MASK;        
buffer= (uint16)(CY_GET_REG32((reg32 *)(ADC_SAR_CHAN_RESULT_IND )) & ADC_RESULT_MASK);

Now I will change the configuration from "Debug" to "Release" as Bob said, and then I will test again.

Obs. I don't know what is a "pin-flip" and how to measure time with this.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

A pin flip, basically you place a pin on schematic, then just before

   

for( ) to collect samples set it high in code, then upon exiting code

   

loop set it low. Using oscilloscope you can then look at pin, and

   

measure its high time which was time to collect all samples.

   

 

   

If you want to be super precise you can look at .lst file and subtract

   

the number of machine cycles associated with the pin flip and for( )

   

loop code from the measured amount.

   

 

   

Basically the two lines of code Bob used a pointer right into

   

the result register of the A/D essentially bypassing compiler

   

interpretation. Looking at .lst file for both approaches you can

   

see the code reduction achieved. You can always look at inline

   

assembly to see if you can achieve even more thruput.

   

 

   

Regards, Dana.

0 Likes
Anonymous
Not applicable

Thank you very much for the explanation Dana.

   


And, Someone could explain me Why when I change the resolution from 12 to 8 bits the sample rate does not increase.
I did the test with the archive sent by Bob and the sample rate is the same approximately (600 Ksps).

   

Bob when you test in your lab let me know.

Regards Adonis Leal

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

If you select clock. set it to 18 Mhz, and your channel is set to ALT, 8 bits,

   

you will see the sample rate rises to > 1.2 Msps.

   

 

   

PSOC 4, 42xx family.

   

 

   

Regards, Dana.

0 Likes
Anonymous
Not applicable

Yes Dana, theoretically yes, but when I tested I got the same 61 samples for each 100us. 

I think that the lost time it is in the transfer of data to array (buffer).

So, if the Psoc 4 takes 1us to converter AD,  It takes 0.63us to transfer the data to the array.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

I think if we count instruction clocks in .lst file we will verify

   

the results you are getting. Which leads us to the only possible

   

conclusion, DMA would solve the problem if PSOC 4 had it.

   

 

   

Prices recently were dropped on PSOC 3 / 5LP families, not of

   

course to the PSOC 4 levels. That has enabled me to move a

   

design crying put for a better part from PSOC 1 biggest part to

   

a 5LP, and leave room for growth.

   

 

   

What actually is driving the spec / need for the SAR performance

   

you are looking for ?There are PSOC families that have 2 SARs

   

in them, one could imagine interleaving them to double the max

   

HW rate. Along with the DMA of course.

   

 

   

Regards, Dana.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Here is the before Bob (BB) and after Bob (AB) asm code -

   

 

   

    

   

          

                                           

  29:.\main.c      ****     for(;;)

  30:.\main.c      ****     {

  31:.\main.c      ****        

  32:.\main.c      ****                   for (i=0; i<=500; i++)

  50                          .loc 1 32 0

  51 0018 0023                mov   r3, #0

  52 001a 1D4A                ldr   r2, .L7+4

  53 001c D219                add   r2, r2, r7

  54 001e 1360                str   r3, [r2]

  55 0020 18E0                b     .L2

  56                    .L3:

  33:.\main.c      ****                   {     

  34:.\main.c      ****                 ADC_IsEndConversion(ADC_WAIT_FOR_RESULT);

  57                          .loc 1 34 0 discriminator 2

  58 0022 0220                mov   r0, #2

  59 0024 FFF7FEFF            bl      ADC_IsEndConversion

  35:.\main.c      ****             buffer= ADC_GetResult16(0); 

  60                          .loc 1 35 0 discriminator 2

  61 0028 0020                mov   r0, #0

  62 002a FFF7FEFF            bl      ADC_GetResult16

  63 002e 031C                mov   r3, r0

  64 0030 191C                mov   r1, r3

  65 0032 184B                ldr   r3, .L7+8

  66 0034 FF20                mov   r0, #255

  67 0036 C000                lsl   r0, r0, #3

  68 0038 C019                add   r0, r0, r7

  69 003a C318                add   r3, r0, r3

  70 003c 1448                ldr   r0, .L7+4

  71 003e C019                add   r0, r0, r7

  72 0040 0268                ldr   r2, [r0]

  73 0042 9200                lsl   r2, r2, #2

  74 0044 D150                str   r1, [r2, r3]

  32:.\main.c      ****                   for (i=0; i<=500; i++)

  75                          .loc 1 32 0 discriminator 2

  76 0046 124A                ldr   r2, .L7+4

  77 0048 D219                add   r2, r2, r7

  78 004a 1368                ldr   r3, [r2]

_ARM GAS  C:\Users\Dana\AppData\Local\Temp\ccG2mVQa.s                   page 3

 

 

  79 004c 0133                add   r3, r3, #1

  80 004e 1048                ldr   r0, .L7+4

  81 0050 C019                add   r0, r0, r7

  82 0052 0360                str   r3, [r0]

  29:.\main.c      ****     for(;;)

  30:.\main.c      ****     {

  31:.\main.c      ****        

  32:.\main.c      ****                   for (i=0; i<=500; i++)

  50                          .loc 1 32 0

  51 0018 0023                mov   r3, #0

  52 001a 1F4A                ldr   r2, .L9+4

  53 001c D219                add   r2, r2, r7

  54 001e 1360                str   r3, [r2]

  55 0020 1DE0                b     .L2

  56                    .L8:

  33:.\main.c      ****                   {     

  34:.\main.c      **** //              ADC_IsEndConversion(ADC_WAIT_FOR_RESULT);

  35:.\main.c      **** //          buffer= ADC_GetResult16(0); 

  36:.\main.c      ****             

  37:.\main.c      ****             while(!(ADC_SAR_INTR_REG & ADC_EOS_MASK)){}            // Wait for ADC result ready

  57                          .loc 1 37 0

  58 0022 C046                mov   r8, r8

  59                    .L3:

  60                          .loc 1 37 0 is_stmt 0 discriminator 1

  61 0024 1D4B                ldr   r3, .L9+8

  62 0026 1A68                ldr   r2, [r3]

  63 0028 0123                mov   r3, #1

  64 002a 1340                and   r3, r2

  65 002c FAD0                beq   .L3

  38:.\main.c      ****             ADC_SAR_INTR_REG = ADC_EOS_MASK;                  //    Reset bit again

  66                          .loc 1 38 0 is_stmt 1

  67 002e 1B4B                ldr   r3, .L9+8

  68 0030 0122                mov   r2, #1

  69 0032 1A60                str   r2, [r3]

  39:.\main.c      ****                   buffer= (uint16)(CY_GET_REG32((reg32 *)(ADC_SAR_CHAN_RESULT_IND )) & ADC_RESULT_MASK); //    Get

  70                          .loc 1 39 0

  71 0034 1A4B                ldr   r3, .L9+12

  72 0036 1B68                ldr   r3, [r3]

  73 0038 9BB2                uxth  r3, r3

  74 003a 191C                mov   r1, r3

  75 003c 194B                ldr   r3, .L9+16

_ARM GAS  C:\Users\Dana\AppData\Local\Temp\ccx2brXp.s                   page 3

 

 

  76 003e FF20                mov   r0, #255

  77 0040 C000                lsl   r0, r0, #3

  78 0042 C019                add   r0, r0, r7

  79 0044 C318                add   r3, r0, r3

  80 0046 1448                ldr   r0, .L9+4

  81 0048 C019                add   r0, r0, r7

  82 004a 0268                ldr   r2, [r0]

  83 004c 9200                lsl   r2, r2, #2

  84 004e D150                str   r1, [r2, r3]

0 Likes
Anonymous
Not applicable

Hi everybody, I'm here again. 

   

Recently I got the CY8CKIT-059 PSoC® 5LP Prototyping Kit, and I would like to use the same project I did in Psoc 4. But is not working. Someone could take a look at the code?

   

 

   

My issue is the same, to sample 1000 samples with 1Msps speed and then send using UART.

   

 

   

#include <project.h>

   

#include <stdio.h>

   

#define BuffSize 1001 // Size of ADC buffer (1200 amostras)

   

 

   

int16 buffer[1000]; // Conversion buffer

   

 

   

int main()

   

{

   

char8 a[32];

   

int16 i=0;

   

    

   

    PWM_1_Start();

   

Opamp_Start();

   

    Clock_Start();

   

ADC_Start(); // Setup the adc

   

ADC_StartConvert(); // Start conversion at 1 Msmpl/s

   

UART_Start();

   

   

while(1)    // *** Main loop

   

    {

   

        

   

for (i=0; i < BuffSize; i++)       // Loop straightened. Taken from the source of ADC.c

   

{

   

while(!(ADC_SAR_INTR_REG & ADC_EOS_MASK)){} // Wait for ADC result ready

   

         ADC_SAR_INTR_REG = ADC_EOS_MASK;                //Reset bit agai

   

buffer= (uint16)(CY_GET_REG32((reg32 *)(ADC_SAR_CHAN_RESULT_IND )) & ADC_RESULT_MASK); 

   

}

   

   

    for (i=0; i < BuffSize; i++) 

   

  {

   

sprintf(a, "%i" ,buffer);

   

UART_UartPutString(a);

   

UART_UartPutString("\n");

   

  }

   

    }

   

}

   

  

   
        
0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Probably your loop destroys some information. you write

   

for (i=0; i < BuffSize; i++)       // Loop straightened. Taken from the source of ADC.c

   

{

   

buffer= (uint16)(CY_GET_REG32((reg32 *)(ADC_SAR_CHAN_RESULT_IND )) & ADC_RESULT_MASK); 

   

and i is 1000 at max which is one more(!!!) than buffer may be indexed.

   

 

   

Bob

0 Likes