Where do I get the most accurate sample rate?

I am setting the clock frequency like this (on my CW-Lite, CW1173):

scope = cw.scope()
time.sleep(0.025)
scope.gain.db=55
scope.adc.samples = 24400
scope.adc.offset = 0
scope.adc.basic_mode = "rising_edge"
scope.clock.clkgen_mul = 2
scope.clock.clkgen_div = 26
scope.trigger.triggers = "tio4"
scope.io.tio1 = "serial_rx"
scope.io.tio2 = "serial_tx"
scope.io.hs2 = "disabled"
scope.clock.adc_src = "clkgen_x4"
scope.clock.reset_dcms()
assert(scope.clock.clkgen_locked)
print("Freq: %f"%scope.clock.adc_freq)

With these settings the printed freq is often (not always) 29538459
If I change mul or div it seems that this is no longer true and the printed freq varies a lot each run.

What does this mean? One theory is that the clock is unstable and the reported value is the source of truth - but how long could I trust that value, can the clock freq change during the run?

The reason I want to know is that I need to set an offset quite far in the future and this is done by specifying how many samples to skip - i.e a different samplerate results in me starting at the wrong offset.

Hi,

I’d recommend ignoring clkgen_mul and clkgen_div and just setting the target frequency directly with scope.clock.clkgen_freq. The ADC clock is derived from this clock (adc_src = "clkgen_x4", so the adc clock will run 4 times faster than the target clock), so if you change mul and div, you’ll also change the adc clock frequency.

adc_freq should always be the same with your code above. When you say it varies, how much does it vary by?

I may be setting it the wrong way I guess, here’s an example code with output

import chipwhisperer as cw
import time
seen = set()
while True:
	scope = cw.scope()
	time.sleep(0.025)
	scope.gain.db=55
	scope.adc.samples = 24400
	scope.adc.offset = 0
	scope.adc.basic_mode = "rising_edge"
	scope.clock.clkgen_mul = 2
	scope.clock.clkgen_div = 26
	scope.trigger.triggers = "tio4"
	scope.io.tio1 = "serial_rx"
	scope.io.tio2 = "serial_tx"
	scope.io.hs2 = "disabled"
	scope.clock.adc_src = "clkgen_x4"
	scope.clock.reset_dcms()
	if not scope.clock.clkgen_locked:
		scope.dis()
		continue
	f = scope.clock.adc_freq
	scope.dis()
	if f in seen:
		continue
	seen.add(f)
	print("Freq: %f"%f)

python3 test.py 
Freq: 48030658.000000
Freq: 51110904.000000
Freq: 52136901.000000
Freq: 50004673.000000
Freq: 49042591.000000
Freq: 50990444.000000
Freq: 47339675.000000
Freq: 52138744.000000
Freq: 51089183.000000
Freq: 47835857.000000
Freq: 51035419.000000
Freq: 50678318.000000
Freq: 48169612.000000
Freq: 52105545.000000
Freq: 48953670.000000
Freq: 47056171.000000
Freq: 50646228.000000
Freq: 46930744.000000
Freq: 48152881.000000
Freq: 50901157.000000
Freq: 49988193.000000
Freq: 45784835.000000

–edit–
It does not seem to happen if I instead measure scope.clock.clkgen_freq, is this a better source of truth or simlply consistency giving the same wrong value?

I’d guess this is because you’re rapidly updating the clock’s settings and disconnecting/reconnecting.

You are right! I need to wait before reading the clock (approx 2 seconds)