- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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)?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Cypress has already acknowleged a fix in future Creator release,
to fix PSOC 5 clock tool margin examination.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@HLI,
probably it was the same guy that programmed the SAR/ADC clocks making the same mistake again...
That's human!
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 */
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No DMA in PSOC 4.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I tried without this line:
if(ADC_IsEndConversion(ADC_RETURN_STATUS))
But the speed is the same.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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");
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Datasheet of ADC-SAR page 5 shows pin1[7] for bypass cap.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For best performance use both a .01 Ceramic and for bulk use a polymer tanalum.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This way the sample rate fall to 220ksps, without this line the sample rate is 350ksps.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It is named "Bypass", so it is connected to pin and GND as I understand.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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] |
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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");
}
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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