diff --git a/adafruit_si5351.py b/adafruit_si5351.py index 82df4a9..db84c88 100644 --- a/adafruit_si5351.py +++ b/adafruit_si5351.py @@ -307,7 +307,7 @@ def _configure_registers(self, p1, p2, p3): self._si5351._write_u8(self._base + 6, (p2 & 0x0000FF00) >> 8) self._si5351._write_u8(self._base + 7, (p2 & 0x000000FF)) - def configure_integer(self, pll, divider): + def configure_integer(self, pll, divider, inverted=False): """Configure the clock output with the specified PLL source (should be a PLL instance on the SI5351 class) and specific integer divider. This is the most accurate way to set the clock output @@ -329,17 +329,24 @@ def configure_integer(self, pll, divider): # Clock not inverted, powered up control |= pll.clock_control_enabled control |= 1 << 6 # Enable integer mode. + if inverted: + control |= 0b00010000 # Bit 4 of the control register = CLKx_INV + else: + control &= 0b11101111 # Make sure to turn it off if not inverted self._si5351._write_u8(self._control, control) # Store the PLL and divisor value so frequency can be calculated. self._pll = pll self._divider = divider - def configure_fractional(self, pll, divider, numerator, denominator): + def configure_fractional( + self, pll, divider, numerator, denominator, inverted=False + ): """Configure the clock output with the specified PLL source (should be a PLL instance on the SI5351 class) and specifiec fractional divider with numerator/denominator. Again this is less accurate but has a wider range of output frequencies. """ + # pylint: disable=too-many-arguments if divider >= 2049 or divider <= 3: raise Exception("Divider must be in range 3 to 2049.") if denominator > 0xFFFFF or denominator <= 0: # Prevent divide by zero. @@ -366,6 +373,10 @@ def configure_fractional(self, pll, divider, numerator, denominator): control = 0x0F # 8mA drive strength, MS0 as CLK0 source, # Clock not inverted, powered up control |= pll.clock_control_enabled + if inverted: + control |= 0b00010000 # Bit 4 of the control register = CLKx_INV + else: + control &= 0b11101111 # Make sure to turn it off if not inverted self._si5351._write_u8(self._control, control) # Store the PLL and divisor value so frequency can be calculated. self._pll = pll @@ -441,3 +452,14 @@ def outputs_enabled(self, val): self._write_u8(_SI5351_REGISTER_3_OUTPUT_ENABLE_CONTROL, 0xFF) else: self._write_u8(_SI5351_REGISTER_3_OUTPUT_ENABLE_CONTROL, 0x00) + self.reset_plls() + + def reset_plls(self): + """Reset both PLLs. This is required when the phase between clocks + needs to be non-random. + + See e.g. + + https://groups.io/g/BITX20/topic/si5351a_facts_and_myths/5430607 + """ + self._write_u8(_SI5351_REGISTER_177_PLL_RESET, (1 << 7) | (1 << 5))