Skip to content

Commit c1049b8

Browse files
authored
Merge pull request #27 from mfhepp/inverted_outputs
Support for inverted clocks
2 parents 5bc629b + 6aa8013 commit c1049b8

File tree

1 file changed

+24
-2
lines changed

1 file changed

+24
-2
lines changed

adafruit_si5351.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ def _configure_registers(self, p1, p2, p3):
307307
self._si5351._write_u8(self._base + 6, (p2 & 0x0000FF00) >> 8)
308308
self._si5351._write_u8(self._base + 7, (p2 & 0x000000FF))
309309

310-
def configure_integer(self, pll, divider):
310+
def configure_integer(self, pll, divider, inverted=False):
311311
"""Configure the clock output with the specified PLL source
312312
(should be a PLL instance on the SI5351 class) and specific integer
313313
divider. This is the most accurate way to set the clock output
@@ -329,17 +329,24 @@ def configure_integer(self, pll, divider):
329329
# Clock not inverted, powered up
330330
control |= pll.clock_control_enabled
331331
control |= 1 << 6 # Enable integer mode.
332+
if inverted:
333+
control |= 0b00010000 # Bit 4 of the control register = CLKx_INV
334+
else:
335+
control &= 0b11101111 # Make sure to turn it off if not inverted
332336
self._si5351._write_u8(self._control, control)
333337
# Store the PLL and divisor value so frequency can be calculated.
334338
self._pll = pll
335339
self._divider = divider
336340

337-
def configure_fractional(self, pll, divider, numerator, denominator):
341+
def configure_fractional(
342+
self, pll, divider, numerator, denominator, inverted=False
343+
):
338344
"""Configure the clock output with the specified PLL source
339345
(should be a PLL instance on the SI5351 class) and specifiec
340346
fractional divider with numerator/denominator. Again this is less
341347
accurate but has a wider range of output frequencies.
342348
"""
349+
# pylint: disable=too-many-arguments
343350
if divider >= 2049 or divider <= 3:
344351
raise Exception("Divider must be in range 3 to 2049.")
345352
if denominator > 0xFFFFF or denominator <= 0: # Prevent divide by zero.
@@ -366,6 +373,10 @@ def configure_fractional(self, pll, divider, numerator, denominator):
366373
control = 0x0F # 8mA drive strength, MS0 as CLK0 source,
367374
# Clock not inverted, powered up
368375
control |= pll.clock_control_enabled
376+
if inverted:
377+
control |= 0b00010000 # Bit 4 of the control register = CLKx_INV
378+
else:
379+
control &= 0b11101111 # Make sure to turn it off if not inverted
369380
self._si5351._write_u8(self._control, control)
370381
# Store the PLL and divisor value so frequency can be calculated.
371382
self._pll = pll
@@ -441,3 +452,14 @@ def outputs_enabled(self, val):
441452
self._write_u8(_SI5351_REGISTER_3_OUTPUT_ENABLE_CONTROL, 0xFF)
442453
else:
443454
self._write_u8(_SI5351_REGISTER_3_OUTPUT_ENABLE_CONTROL, 0x00)
455+
self.reset_plls()
456+
457+
def reset_plls(self):
458+
"""Reset both PLLs. This is required when the phase between clocks
459+
needs to be non-random.
460+
461+
See e.g.
462+
463+
https://groups.io/g/BITX20/topic/si5351a_facts_and_myths/5430607
464+
"""
465+
self._write_u8(_SI5351_REGISTER_177_PLL_RESET, (1 << 7) | (1 << 5))

0 commit comments

Comments
 (0)