Skip to content

Commit e09d90f

Browse files
committed
fix phase-offset functionality.
1 parent 1e7313c commit e09d90f

File tree

4 files changed

+387
-33
lines changed

4 files changed

+387
-33
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
from .si5351 import Si5351A_B_GT, Si5351
2+
from .si5351_mini import Si5351_mini

codes/clock_generators/si5351/si5351a.py

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,9 @@ def __init__(self, si, idx, denominator_max = DENOMINATOR_MAX):
103103
self._si = si
104104
self._idx = idx
105105

106-
# set divider first, source second.
107106
self.denominator_max = denominator_max
108-
self._set_divider(self.DIVIDER_DEFAULT)
109107
self._source = None
108+
self._set_divider(self.DIVIDER_DEFAULT)
110109
# self.set_input_source() # need implement
111110

112111

@@ -244,7 +243,14 @@ def _set_parameters(self, p1, p2, p3):
244243

245244

246245
def _post_set_divider(self):
247-
pass
246+
self._maintain_phase_offset()
247+
248+
249+
def _maintain_phase_offset(self):
250+
if self.pll:
251+
# https://groups.io/g/BITX20/topic/si5351a_facts_and_myths/5430607
252+
# need to reset PLL in order to synch phases of outputs.
253+
self.pll.reset()
248254

249255

250256
class _PLL(_MultisynthBase):
@@ -264,7 +270,7 @@ class _PLL(_MultisynthBase):
264270

265271
def __init__(self, si, name, xtal_as_source = True):
266272
self._name = name
267-
super().__init__(si, self.NAMES[name])
273+
super().__init__(si, idx = self.NAMES[name])
268274
self._xtal_as_source = xtal_as_source
269275
self.init()
270276

@@ -463,9 +469,6 @@ def _set_divided_by_4(self, value = True):
463469

464470
self._post_set_divider()
465471

466-
if self.pll:
467-
self.pll.reset() # need to reset PLL after switching mode.
468-
469472

470473
class _Clock(_MultisynthBase):
471474

@@ -490,6 +493,7 @@ def __init__(self, si, idx,
490493
self._set_disable_state(disable_state)
491494
self.set_input_source(source)
492495
self.set_frequency(self._si.FREQ_REF if freq is None else freq)
496+
self.set_phase(PHASE_DEFAULT)
493497

494498

495499
@property
@@ -672,16 +676,6 @@ def _set_divider(self, divider = 1):
672676
self._si._write_element_by_name('R{}_DIV'.format(self._idx), self.R_DIVIDERs[divider])
673677

674678

675-
def _post_set_divider(self):
676-
self._maintain_phase_offset()
677-
678-
679-
def _maintain_phase_offset(self):
680-
if self.phase_offset_enabled: # https://groups.io/g/BITX20/topic/si5351a_facts_and_myths/5430607
681-
if self.pll:
682-
self.pll.reset()
683-
684-
685679
@property
686680
def phase_offset_enabled(self):
687681
if self._idx in range(self.N_MULTISYNTHS_WITH_OUTPUT_SKEW):
@@ -691,13 +685,6 @@ def phase_offset_enabled(self):
691685

692686
def set_phase(self, phase):
693687
self._action = 'set_phase {} idx {}'.format(phase, self._idx)
694-
my_period = 1 / self.freq
695-
offset_seconds = (phase % DEGREES_IN_PI2) / DEGREES_IN_PI2 * my_period
696-
self.set_phase_offset(offset_seconds)
697-
698-
699-
def set_phase_offset(self, offset_seconds = 0):
700-
self._si._action = 'set_phase_offset {}'.format(offset_seconds)
701688

702689
# Set offset_seconds = 0 to disable it.
703690
#
@@ -713,18 +700,33 @@ def set_phase_offset(self, offset_seconds = 0):
713700
# CLKx_PHOFF[4:0] = Round(DesiredOffset(sec) * 4 * FVCO)
714701
# ==> typo, should be [6:0]
715702

716-
if self._idx in range(self.N_MULTISYNTHS_WITH_OUTPUT_SKEW):
717-
if self.multisynth is not None:
718-
self._si.multisynths[self._idx]._set_integer_mode(False)
703+
if self._idx in range(self.N_MULTISYNTHS_WITH_OUTPUT_SKEW) and self.multisynth is not None:
719704

720-
freq_vco = self.pll.freq # PLL
721-
offset = int(round(offset_seconds * 4 * freq_vco))
722-
self._set_phase_offset(offset)
705+
cycle = (phase % DEGREES_IN_PI2) / DEGREES_IN_PI2
706+
freq_vco = self.pll.freq # PLL
707+
708+
freq_min = cycle * freq_vco * 4 / (2 ** 7 - 0.5) # CLKx_PHOFF has 7 bits, must < 128 after rounded.
709+
assert self.freq > freq_min, \
710+
'my freq must be greater than {:0.3e} to have {} degree phase offset.'.format(freq_min, phase)
711+
712+
my_period = 1 / self.freq
713+
offset_seconds = cycle * my_period
714+
offset = int(round(offset_seconds * 4 * freq_vco))
715+
self._set_phase_offset(offset)
716+
717+
if phase != 0:
718+
self.multisynth._set_integer_mode(False)
719+
else:
720+
self.multisynth.restore_frequency() # restore integer mode if applicable.
721+
722+
self._maintain_phase_offset() # need to reset PLL
723723

724724

725725
@property
726726
def phase_offset(self):
727-
return self._si.map.elements['CLK{}_PHOFF'.format(self._idx)]['element'].value
727+
if self._idx in range(self.N_MULTISYNTHS_WITH_OUTPUT_SKEW) and self.multisynth is not None:
728+
return self._si.map.elements['CLK{}_PHOFF'.format(self._idx)]['element'].value
729+
return 0
728730

729731

730732
@property
@@ -740,6 +742,8 @@ def _set_phase_offset(self, offset = 0):
740742
# CLKx_PHOFF[6:0] is an unsigned integer with one LSB equivalent to a time delay of
741743
# Tvco/4, where Tvco is the period of the VCO/PLL associated with this output.
742744

745+
# assert 0 <= offset < 2 ** 7, 'offset ({}) should be less than 128.'.format(offset)
746+
743747
self._si._write_element_by_name('CLK{}_PHOFF'.format(self._idx), offset & 0x7F)
744748

745749

@@ -926,8 +930,8 @@ def init(self):
926930
for i in self.channels_in_use:
927931
self.clocks[i].power_down(False) # Just power up clocks in use.
928932

929-
self.reset_plls()
930933
self.start()
934+
self.reset_plls()
931935

932936

933937
def reset_plls(self):

notebooks/tests/Functional test/Quadrature Phase Split test with FTDI.ipynb

Lines changed: 349 additions & 0 deletions
Large diffs are not rendered by default.

notebooks/tools/上傳檔案 - Si5351.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@
338338
},
339339
{
340340
"cell_type": "code",
341-
"execution_count": 65,
341+
"execution_count": 14,
342342
"metadata": {
343343
"scrolled": false
344344
},

0 commit comments

Comments
 (0)