mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-04 23:17:47 +00:00
50778af656
This adds many missing functions needed for convenient use that are reinterpreted from the C code in https://github.com/dmalnati/picoinf Thank you! Signed-off-by: deadprogram <ron@hybridgroup.com>
121 lines
4.2 KiB
Go
121 lines
4.2 KiB
Go
package main
|
|
|
|
import (
|
|
"machine"
|
|
"time"
|
|
|
|
"tinygo.org/x/drivers/si5351"
|
|
)
|
|
|
|
// Simple demo of the SI5351 clock generator.
|
|
// This is like the Arduino library example:
|
|
// https://github.com/adafruit/Adafruit_Si5351_Library/blob/master/examples/si5351/si5351.ino
|
|
// Which will configure the chip with:
|
|
// - PLL A at 900mhz
|
|
// - PLL B at 616.66667mhz
|
|
// - Clock 0 at 112.5mhz, using PLL A as a source divided by 8
|
|
// - Clock 1 at 13.5531mhz, using PLL B as a source divided by 45.5
|
|
// - Clock 2 at 10.76khz, using PLL B as a source divided by 900 and further divided with an R divider of 64.
|
|
|
|
func main() {
|
|
time.Sleep(5 * time.Second)
|
|
|
|
println("Si5351 Clockgen Test")
|
|
println()
|
|
|
|
// Configure I2C bus
|
|
machine.I2C0.Configure(machine.I2CConfig{})
|
|
|
|
// Create driver instance
|
|
clockgen := si5351.New(machine.I2C0)
|
|
|
|
// Verify device wired properly
|
|
connected, err := clockgen.Connected()
|
|
if err != nil {
|
|
println("Unable to read device status")
|
|
time.Sleep(time.Second)
|
|
}
|
|
if !connected {
|
|
for {
|
|
println("Unable to detect si5351 device")
|
|
time.Sleep(time.Second)
|
|
}
|
|
}
|
|
|
|
// Initialise device
|
|
clockgen.Configure()
|
|
|
|
// Now configue the PLLs and clock outputs.
|
|
// The PLLs can be configured with a multiplier and division of the on-board
|
|
// 25mhz reference crystal. For example configure PLL A to 900mhz by multiplying
|
|
// by 36. This uses an integer multiplier which is more accurate over time
|
|
// but allows less of a range of frequencies compared to a fractional
|
|
// multiplier shown next.
|
|
clockgen.ConfigurePLL(si5351.PLL_A, 36, 0, 1) // Multiply 25mhz by 36
|
|
println("PLL A frequency: 900mhz")
|
|
|
|
// And next configure PLL B to 616.6667mhz by multiplying 25mhz by 24.667 using
|
|
// the fractional multiplier configuration. Notice you specify the integer
|
|
// multiplier and then a numerator and denominator as separate values, i.e.
|
|
// numerator 2 and denominator 3 means 2/3 or 0.667. This fractional
|
|
// configuration is susceptible to some jitter over time but can set a larger
|
|
// range of frequencies.
|
|
clockgen.ConfigurePLL(si5351.PLL_B, 24, 2, 3) // Multiply 25mhz by 24.667 (24 2/3)
|
|
println("PLL B frequency: 616.6667mhz")
|
|
|
|
// Now configure the clock outputs. Each is driven by a PLL frequency as input
|
|
// and then further divides that down to a specific frequency.
|
|
// Configure clock 0 output to be driven by PLL A divided by 8, so an output
|
|
// of 112.5mhz (900mhz / 8). Again this uses the most precise integer division
|
|
// but can't set as wide a range of values.
|
|
clockgen.ConfigureMultisynth(0, si5351.PLL_A, 8, 0, 1) // Divide by 8 (8 0/1)
|
|
println("Clock 0: 112.5mhz")
|
|
|
|
// Next configure clock 1 to be driven by PLL B divided by 45.5 to get
|
|
// 13.5531mhz (616.6667mhz / 45.5). This uses fractional division and again
|
|
// notice the numerator and denominator are explicitly specified. This is less
|
|
// precise but allows a large range of frequencies.
|
|
clockgen.ConfigureMultisynth(1, si5351.PLL_B, 45, 1, 2) // Divide by 45.5 (45 1/2)
|
|
println("Clock 1: 13.5531mhz")
|
|
|
|
// Finally configure clock 2 to be driven by PLL B divided once by 900 to get
|
|
// down to 685.15 khz and then further divided by a special R divider that
|
|
// divides 685.15 khz by 64 to get a final output of 10.706khz.
|
|
clockgen.ConfigureMultisynth(2, si5351.PLL_B, 900, 0, 1) // Divide by 900 (900 0/1)
|
|
// Set the R divider, this can be a value of:
|
|
// - R_DIV_1: divider of 1
|
|
// - R_DIV_2: divider of 2
|
|
// - R_DIV_4: divider of 4
|
|
// - R_DIV_8: divider of 8
|
|
// - R_DIV_16: divider of 16
|
|
// - R_DIV_32: divider of 32
|
|
// - R_DIV_64: divider of 64
|
|
// - R_DIV_128: divider of 128
|
|
clockgen.ConfigureRdiv(2, si5351.R_DIV_64)
|
|
println("Clock 2: 10.706khz")
|
|
|
|
// After configuring PLLs and clocks, enable the outputs.
|
|
clockgen.EnableOutputs()
|
|
|
|
time.Sleep(time.Second)
|
|
|
|
clockgen.DisableOutputs()
|
|
println("All outputs disabled for 5 seconds")
|
|
time.Sleep(5 * time.Second)
|
|
|
|
// Now use SetFrequency to re-set the frequencies of the outputs
|
|
on := false
|
|
for {
|
|
if on {
|
|
println("Setting Clock 0 output off")
|
|
clockgen.OutputEnable(0, false)
|
|
on = false
|
|
} else {
|
|
println("Setting Clock 0 output to 100mhz")
|
|
clockgen.SetFrequency(100*machine.MHz, 0, si5351.PLL_A)
|
|
on = true
|
|
}
|
|
time.Sleep(5 * time.Second)
|
|
}
|
|
}
|