vikkubaliga wrote: ↑Thu Feb 02, 2023 5:38 amEXACTLY!! THAT IS MY POINT TOO!!! If I'm able to read the data at 40Mhz, and I'm able get very good data [Extracting pins data from the captured GPLEV0 readings, removing the error data samples that were captured when the ADC data pins were transitioning to the next data sate, and then plotting the data shows a beautiful sine wave. With good connection: 1Mhz sine wave will have 10 groups of same value points] then why can I not get the clock as it is??
But:1. The pin I set as input, I've verified multiple times using raspi-gpio.
2. I'm reading the correct pin.
3. To verify, I've generated a square wave of multiple frequencies in another CM4. Connected that output GPIO of the generating CM4 to my reading CM4, I'm able to read a good square wave up to 7Mhz. After 7Mhz, I'm not able to read this signal too!!
Right, so my best guess is that you have created a low-pass filter, with a cutoff around 7 MHz.
In your photos, it looks like you have a series resistor between the oscillator signal and the input pin - what value is this? Depending on your layout, you may have significant shunt capacitance between the I/O pin and ground. For example, if you have (say) 20 picofarads of capacitance, and have used a 10K series resistor, then you have created a low-pass filter with an approximate cutoff of 5 MHz, which would explain the symptoms your are seeing..
Re: Recommended GPIO to read a 10Mhz clock
Re: Recommended GPIO to read a 10Mhz clock
Right, so my best guess is that you have created a low-pass filter, with a cutoff around 7 MHz.jayben wrote: ↑Thu Feb 02, 2023 9:38 amvikkubaliga wrote: ↑Thu Feb 02, 2023 5:38 amEXACTLY!! THAT IS MY POINT TOO!!! If I'm able to read the data at 40Mhz, and I'm able get very good data [Extracting pins data from the captured GPLEV0 readings, removing the error data samples that were captured when the ADC data pins were transitioning to the next data sate, and then plotting the data shows a beautiful sine wave. With good connection: 1Mhz sine wave will have 10 groups of same value points] then why can I not get the clock as it is??
But:1. The pin I set as input, I've verified multiple times using raspi-gpio.
2. I'm reading the correct pin.
3. To verify, I've generated a square wave of multiple frequencies in another CM4. Connected that output GPIO of the generating CM4 to my reading CM4, I'm able to read a good square wave up to 7Mhz. After 7Mhz, I'm not able to read this signal too!!
In your photos, it looks like you have a series resistor between the oscillator signal and the input pin - what value is this? Depending on your layout, you may have significant shunt capacitance between the I/O pin and ground. For example, if you have (say) 20 picofarads of capacitance, and have used a 10K series resistor, then you have created a low-pass filter with an approximate cutoff of 5 MHz, which would explain the symptoms you are seeing..
Re: Recommended GPIO to read a 10Mhz clock
I don't think you have established that you can "read in 40MHz data".vikkubaliga wrote: ↑Thu Feb 02, 2023 5:38 amEXACTLY!! THAT IS MY POINT TOO!!! If I'm able to read the data at 40Mhz, and I'm able get very good data [Extracting pins data from the captured GPLEV0 readings, removing the error data samples that were captured when the ADC data pins were transitioning to the next data sate, and then plotting the data shows a beautiful sine wave. With good connection: 1Mhz sine wave will have 10 groups of same value points] then why can I not get the clock as it is??
What you have shown is that you can sample at 40Msample/s, but what you read was nowhere close to 40MHz data. As you remarked, you got multiple repeated values because your sine wave was much slower than 10MHz.
You may have established that you can read something less than 7MHz data by capturing a ~ 7MHz clock.
You mentioned you inspected the clock waveform on a CRO. What did that waveform look like at right the gpio pin?
What is the bandwith of your CRO?
Do you get the same result capturing the clock when the 'Scope is connected to the pin?
-
- Posts: 32
- Joined: Wed Oct 19, 2022 9:39 am
Re: Recommended GPIO to read a 10Mhz clock
Oops! Sorry! I get it now. Yes. I'm not able to read 40Mhz data. by "Able to read data at 40Mhz" I mean I'm able to read the data, with my sampling frequency being 40Mhz. That is, as u said, I'm able to read at 40MSPS. In all my prior posts, this is wat I mean. Sorry for the confusion caused.
Yes. For direct reading from a GPIO I can read only less than 7Mhz, by capturing a square wave generated by another CM4.
However, the data rate from the ADC is 10MSPS. I'm able to capture it.
The waveform is not exactly square. It is a bit distorted. But I think it is not so degraded that it cannot be read by the GPIO pins.
Here is my 10Mhz clock signal, from the oscillator, at the GPIO pin, from the CRO:
The CRO is RIGOL DS1104, 100Mhz, 1GSa/s
Yes, the results are same irrespective of the scope being connected.
-
- Posts: 32
- Joined: Wed Oct 19, 2022 9:39 am
Re: Recommended GPIO to read a 10Mhz clock
Yes. the resistor is 100Ohms.
Is there a way by which I can verify this? my measuring anything on my PCB?jayben wrote: ↑Thu Feb 02, 2023 9:38 amDepending on your layout, you may have significant shunt capacitance between the I/O pin and ground. For example, if you have (say) 20 picofarads of capacitance, and have used a 10K series resistor, then you have created a low-pass filter with an approximate cutoff of 5 MHz, which would explain the symptoms you are seeing..
-
- Posts: 32
- Joined: Wed Oct 19, 2022 9:39 am
Re: Recommended GPIO to read a 10Mhz clock
Yes. The ADC data sheet says I must read the data lines at the rising edge of the clock.
I'm trying to read all the data at once. After capturing, I discard the samples where clock is low, considering only the first sample when the clock just got high.
If using rising edge GPIO interrupts, can the IRQ fire at that rate? 10M times a second? Also, at the interrupt routine or callback, I must read and store the GPLEV0 register in my array or some memory location. Can all this happen 10M times a second?
If it is possible, I can use riding edge interrupt instead of the method I'm using now. I'm going with this method just because I thought this method is simpler and has less processing to do.
Regarding the code I posted earlier about using the ternary operator, I shall try your method.
I'm confused about wat to do is majorly because without any processing, with simple data capture in a tight loop, the clock is not able to be read even though the other 24 ADC lines (12 each of the 2 ADCs) are able to be read...
Re: Recommended GPIO to read a 10Mhz clock
On a very quick look at the DMA peripheral in the Pi, it has the ability to use an input from a peripheral to 'pace' transfers. Might there be a way to use an edge of your 10MHz sampling clock to trigger this? (If you can't trigger directly from a pin, can you trigger off a timer which also outputs the 10MHz clock?)
-
- Posts: 32
- Joined: Wed Oct 19, 2022 9:39 am
Re: Recommended GPIO to read a 10Mhz clock
Pacing the data capture is not an issue. I'm able to read at higher speeds. My objective is to pace the transfer in sync with a common timing source for both ADC as well as the reading procedure.stevend wrote: ↑Thu Feb 02, 2023 1:42 pmOn a very quick look at the DMA peripheral in the Pi, it has the ability to use an input from a peripheral to 'pace' transfers. Might there be a way to use an edge of your 10MHz sampling clock to trigger this? (If you can't trigger directly from a pin, can you trigger off a timer which also outputs the 10MHz clock?)
Thats is why I'm trying to read the external 10Mhz clock. [ Generating a clock signal using a timer in CM4 itself and using this signal as clock reference for the ADC will solve the issue if: ADC can read the 10Mhz signal generated by the CM4 and the timer is accurate enough. Given the general-purpose OS and the timer accuracy, this option is ruled out.]
The first part, as u suggested, to trigger the DMA (or simple read via IRQ) via peripheral pin is the only method to do this. I will try to read the GPLEV0 (or system timer CL0) when a rising edge interrupt occurs.
Later on, I shall try DMA as suggested by many.
-
- Raspberry Pi Engineer & Forum Moderator
- Posts: 4954
- Joined: Mon Sep 29, 2014 1:07 pm
- Location: Cambridge
Re: Recommended GPIO to read a 10Mhz clock
@stevend As far as I know there is no way to use a GPIO as the source of a pacing signal - the "dreqs" are strictly on-chip signals hooked up to peripheral interfaces, which in turn base derive them from FIFO levels, etc.
-
- Posts: 32
- Joined: Wed Oct 19, 2022 9:39 am
Re: Recommended GPIO to read a 10Mhz clock
I tried the following combinations with input to ADC as 1Mhz sine wave:dp11 wrote: ↑Thu Feb 02, 2023 9:18 amI think it isn't at this level about loop complexity but how the compiler implements the ternary operator. I suspect it uses a branch instruction. My pseudo code doesn't use a branch instruction and it is unlikely ( not impossible) that it will compile to a branch instruction. But who knows I haven't tested it.
Code: Select all
// Without clock check: Good sine wave, with no missng ADC samples
[*] { volatile uint32_t raw = base[13]; arr[++idx] = raw; } // capture speed = 14 samples per wave, clock pin - random high and low
[*] { uint32_t raw = base[13]; arr[++idx] = raw; } // 20 samples per wave, clock not read, clock pin - random high and low
// With clock check, improper sine wave, samples missed in between, 6-9 samples per wave
[*] { uint32_t raw = base[13]; arr[idx] = raw; idx += (raw&1); }
[*] { uint32_t raw = base[13]; arr[idx] = raw; idx = idx + (raw&1); }
[*] {volatile uint32_t raw = base[13]; arr[idx] = raw; idx = idx + (raw&1); }
// Using a u32 prev_data, check for rising edge: improper sine wave, samples missed in between, 5-8 samples per wave
[*] { volatile uint32_t raw = base[13]; arr[idx] = raw; idx = idx + ((prev_data ^ raw)&1); prev_data = raw; }
[*] ]{ uint32_t raw = base[13]; arr[idx] = raw; idx = idx + ((prev_data ^ raw)&1); prev_data = raw; }
Re: Recommended GPIO to read a 10Mhz clock
vikkubaliga wrote: ↑Thu Feb 02, 2023 3:21 pmI tried the following combinations with input to ADC as 1Mhz sine wave:dp11 wrote: ↑Thu Feb 02, 2023 9:18 amI think it isn't at this level about loop complexity but how the compiler implements the ternary operator. I suspect it uses a branch instruction. My pseudo code doesn't use a branch instruction and it is unlikely ( not impossible) that it will compile to a branch instruction. But who knows I haven't tested it.
Code: Select all
// Without clock check: Good sine wave, with no missng ADC samples [*] { volatile uint32_t raw = base[13]; arr[++idx] = raw; } // capture speed = 14 samples per wave, clock pin - random high and low [*] { uint32_t raw = base[13]; arr[++idx] = raw; } // 20 samples per wave, clock not read, clock pin - random high and low // With clock check, improper sine wave, samples missed in between, 6-9 samples per wave [*] { uint32_t raw = base[13]; arr[idx] = raw; idx += (raw&1); } [*] { uint32_t raw = base[13]; arr[idx] = raw; idx = idx + (raw&1); } [*] {volatile uint32_t raw = base[13]; arr[idx] = raw; idx = idx + (raw&1); } // Using a u32 prev_data, check for rising edge: improper sine wave, samples missed in between, 5-8 samples per wave [*] { volatile uint32_t raw = base[13]; arr[idx] = raw; idx = idx + ((prev_data ^ raw)&1); prev_data = raw; } [*] ]{ uint32_t raw = base[13]; arr[idx] = raw; idx = idx + ((prev_data ^ raw)&1); prev_data = raw; }
So in the beginning you said you got 40MSPS. Am I reading the the above correctly, for your 1st case that you now only are getting 20MSPS ?
-
- Posts: 32
- Joined: Wed Oct 19, 2022 9:39 am
Re: Recommended GPIO to read a 10Mhz clock
Yes, if I remove the local u32 raw and directly assign it to the array (as seen in my first code snippet), I still get 40MSPS.
Also, while compiling using gcc, the performance varies if I remove some of the flags like unroll loops.
I'm using the below to compile:
Code: Select all
g++ -o hsdaq_data_acq hsdaq_data_acq.cpp -O3 -W -Wall -D_XOPEN_SOURCE=500 -funroll-all-loops -ftree-vectorize -Ofast -lpthread -static
Re: Recommended GPIO to read a 10Mhz clock
so are you saying ?
if so I'm surprised.
Code: Select all
{ uint32_t raw = base[13]; arr[++idx] = raw; } // is 20MSPS
{ uint32_t arr[++idx] = base[13]; } // is 40MSPS
-
- Posts: 32
- Joined: Wed Oct 19, 2022 9:39 am
Re: Recommended GPIO to read a 10Mhz clock
Sorry, my bad. It is indeed 40MSPS. Both are 40MSPS. I rechecked them now. They're both the same speed, at 40MSPS.dp11 wrote: ↑Thu Feb 02, 2023 5:33 pmso are you saying ?if so I'm surprised.Code: Select all
{ uint32_t raw = base[13]; arr[++idx] = raw; } // is 20MSPS { uint32_t arr[++idx] = base[13]; } // is 40MSPS
I was trying multiple combinations yesterday, including the compilation flag changes. I might have missed something there.
They're both 40MSPS.
Adding a volatile will bring down the speed to 14. That is as expected. Without the volatile keyword, having a local variable or not does not make a difference. It doesn't make sense to say adding local variable will halve the performance

Re: Recommended GPIO to read a 10Mhz clock
It's the base[13] that is volatile (changed by something external to the code), not the variable raw. I don't think volatile on raw does anything useful.dp11 wrote: ↑Thu Feb 02, 2023 4:14 pmCode: Select all
[*] { volatile uint32_t raw = base[13]; arr[++idx] = raw; } // capture speed = 14 samples per wave, clock pin - random high and low
-
- Posts: 32
- Joined: Wed Oct 19, 2022 9:39 am
-
- Posts: 32
- Joined: Wed Oct 19, 2022 9:39 am
Re: Recommended GPIO to read a 10Mhz clock
So, I tried DMA to read from the GPLEV0 as well as system timer CL0 for verification. The results are poor. I'm not sure if my expectations were higher.
Modified the code in this repo to read from CM4. (The master branch has peripheral base address of some other versions.)
https://github.com/fandahao17/Raspberry-Pi-DMA-Tutorial
On simply reading from the system timer, the results are slower than my tight loop. About 4MSPS to 8MSPS. My tight loop has about 40MSPS.
[Not using 2D stride, just with tx_len = 4 per db ]
Plotting the data by reading from the GPLEV0 makes no sense cause my capturing speed is less than my data speed.
Modified the code in this repo to read from CM4. (The master branch has peripheral base address of some other versions.)
https://github.com/fandahao17/Raspberry-Pi-DMA-Tutorial
On simply reading from the system timer, the results are slower than my tight loop. About 4MSPS to 8MSPS. My tight loop has about 40MSPS.
[Not using 2D stride, just with tx_len = 4 per db ]
Code: Select all
DMA 27: 356870536
DMA 28: 356870536
DMA 29: 356870537
DMA 30: 356870537
DMA 31: 356870537
DMA 32: 356870537
DMA 33: 356870537
DMA 34: 356870537
DMA 35: 356870538
DMA 36: 356870538
DMA 37: 356870538
DMA 38: 356870538
DMA 39: 356870538
DMA 40: 356870538
DMA 41: 356870539
DMA 42: 356870539
DMA 43: 356870539
DMA 44: 356870539
DMA 45: 356870540
DMA 46: 356870540
DMA 47: 356870540
DMA 48: 356870540
DMA 49: 356870540
DMA 50: 356870540
DMA 51: 356870541
DMA 52: 356870541
DMA 53: 356870541
DMA 54: 356870541
DMA 55: 356870541
DMA 56: 356870541
DMA 57: 356870542
DMA 58: 356870542
DMA 59: 356870542
DMA 60: 356870542
DMA 61: 356870542
DMA 62: 356870543
DMA 63: 356870543
DMA 64: 356870543
DMA 65: 356870543
DMA 66: 356870543
DMA 67: 356870544
Re: Recommended GPIO to read a 10Mhz clock
pigpio uses DMA to sample the GPIO. Sampling at sub-microsecond intervals seems to saturate the memory buses and make timing inaccurate. DMA will not get anywhere near the sample rate you want.
Re: Recommended GPIO to read a 10Mhz clock
Code: Select all
uint32_t rawa=0,rawb=0,prev_dataa=0,prev_datab=0;
{
rawb = base[13];
arr[idx] = rawa;
idx = idx + ((prev_data ^ rawa)&1);
prev_data = rawa;
rawa = base[13];
arr[idx] = rawb;
idx = idx + ((prev_data ^ rawb)&1);
prev_data = rawb;
}
-
- Raspberry Pi Engineer & Forum Moderator
- Posts: 4954
- Joined: Mon Sep 29, 2014 1:07 pm
- Location: Cambridge
Re: Recommended GPIO to read a 10Mhz clock
Is the intention to latch on both rising and falling edges?
Re: Recommended GPIO to read a 10Mhz clock
Rockets are loud.
https://astro-pi.org
https://astro-pi.org
-
- Posts: 32
- Joined: Wed Oct 19, 2022 9:39 am
Re: Recommended GPIO to read a 10Mhz clock
Short answer: NO.
Long answer: Nope. Intention is just to be able to read the clock pin, connected to a GPIO. the clock being generated by an oscillator clock IC or another CM4.
The above is required to be in sync with my capture of the ADC data pins and them transiting to next data stage.
Ideally, I need to catch the rising edge and read at that instant.
Or I can just read the data at bulk, and then, at my receiving/processing end, consider the clock pin as the "data valid" bit to discard all samples were that bit was low, or discard all samples except the one where that bit changed to high.
Re: Recommended GPIO to read a 10Mhz clock
The actual requirement is to read data at 10MHz. on the rising edge of the 10MHz clock
-
- Posts: 32
- Joined: Wed Oct 19, 2022 9:39 am
Re: Recommended GPIO to read a 10Mhz clock
The SMI interface is 18bits data. My requirement is 12 bits, 2 ch data. That is 24 bits, plus a clock signal (If same clock can be supplied to both ADC, else one bit per clock)jdb wrote: ↑Fri Feb 03, 2023 11:14 amWhy not use SMI as a bus analyser?
https://github.com/raspberrypi/linux/bl ... _smi_dev.c
So, SMI is not possible.
Anyways, except the clock, I'm able to read data at about 40MSPS. Only clock pin is unable to be read.
Not sure if it is hardware or software issue.
-
- Posts: 32
- Joined: Wed Oct 19, 2022 9:39 am
Re: Recommended GPIO to read a 10Mhz clock
Is there a way I can measure something on the PCB and verify if the filtering effect is produced?jayben wrote: ↑Thu Feb 02, 2023 9:39 amRight, so my best guess is that you have created a low-pass filter, with a cutoff around 7 MHz.
In your photos, it looks like you have a series resistor between the oscillator signal and the input pin - what value is this? Depending on your layout, you may have significant shunt capacitance between the I/O pin and ground. For example, if you have (say) 20 picofarads of capacitance, and have used a 10K series resistor, then you have created a low-pass filter with an approximate cutoff of 5 MHz, which would explain the symptoms you are seeing..
I'm not yet sure if this a GPIO capability issue or a software issue or hardware connections issue...
I'm just stuck with by finding:
Able to read from ADC data lines (parallel output). The ADC data rate is 10MSPS.
I'm able to capture them without missing any samples. [At regular interval, I miss about 10 ADC samples, that's another issue though]
To sync my data capture with the ADC parallel port, it does not have "Data Ready" pin. So, I must use clock as data ready.
I'm not able to read this clock [connected as shown in the pic, using an external wire], which is 10Mhz. Nor am I able to read frequencies higher than 7Mhz, generated by another CM4 module.
As you suggest, if it's a hardware issue, can you please provide me some leads as to wat I can possibly measure on my board to collect more info of this issue!