mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-18 21:53:56 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e472cf88c8 | |||
| 2a42fa7cbb |
@@ -28,6 +28,8 @@ const (
|
|||||||
PLL_RESET = 177
|
PLL_RESET = 177
|
||||||
|
|
||||||
CRYSTAL_INTERNAL_LOAD_CAPACITANCE = 183
|
CRYSTAL_INTERNAL_LOAD_CAPACITANCE = 183
|
||||||
|
|
||||||
|
FANOUT_ENABLE = 187
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -77,3 +79,44 @@ const (
|
|||||||
const (
|
const (
|
||||||
SI5351_PLL_C_MAX = 1048575
|
SI5351_PLL_C_MAX = 1048575
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Bit masks for FANOUT_ENABLE register
|
||||||
|
const (
|
||||||
|
CLKIN_ENABLE = (1 << 7)
|
||||||
|
XTAL_ENABLE = (1 << 6)
|
||||||
|
MULTISYNTH_ENABLE = (1 << 4)
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FANOUT_CLKIN = iota
|
||||||
|
FANOUT_XO
|
||||||
|
FANOUT_MS
|
||||||
|
)
|
||||||
|
|
||||||
|
// Clock source selection masks for CLKx_CONTROL registers
|
||||||
|
const (
|
||||||
|
CLK_INPUT_MASK = 0x3 // Bits 0 and 1
|
||||||
|
CLK_INPUT_XTAL = 0x0
|
||||||
|
CLK_INPUT_CLKIN = 0x1
|
||||||
|
CLK_INPUT_MULTISYNTH_0_4 = 0x2
|
||||||
|
CLK_INPUT_MULTISYNTH_N = 0x3
|
||||||
|
)
|
||||||
|
|
||||||
|
// Clock source selection
|
||||||
|
const (
|
||||||
|
CLK_SRC_XTAL = iota
|
||||||
|
CLK_SRC_CLKIN
|
||||||
|
CLK_SRC_MS0
|
||||||
|
CLK_SRC_MS
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CLK_INVERT = 1 << 4
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CLK_DRIVE_STRENGTH_2MA = 0
|
||||||
|
CLK_DRIVE_STRENGTH_4MA = 1
|
||||||
|
CLK_DRIVE_STRENGTH_6MA = 2
|
||||||
|
CLK_DRIVE_STRENGTH_8MA = 3
|
||||||
|
)
|
||||||
|
|||||||
@@ -627,3 +627,163 @@ func (d *Device) GetFreqStep(pll uint8) uint64 {
|
|||||||
|
|
||||||
return pllFreq / SI5351_PLL_C_MAX
|
return pllFreq / SI5351_PLL_C_MAX
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetClockFanout enables or disables the specified clock fanout.
|
||||||
|
// fanout - The fanout to configure, which must be one of:
|
||||||
|
// - FANOUT_CLKIN
|
||||||
|
// - FANOUT_XO
|
||||||
|
// - FANOUT_MS
|
||||||
|
//
|
||||||
|
// enable - true to enable the fanout, false to disable it.
|
||||||
|
func (d *Device) SetClockFanout(fanout int, enable bool) error {
|
||||||
|
if !d.initialised {
|
||||||
|
return ErrNotInitialised
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the current value of the FANOUT_ENABLE register
|
||||||
|
regVal, err := d.rw.Read8(FANOUT_ENABLE)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Modify regVal based on fanout and enable
|
||||||
|
switch fanout {
|
||||||
|
case FANOUT_CLKIN:
|
||||||
|
if enable {
|
||||||
|
regVal |= CLKIN_ENABLE
|
||||||
|
} else {
|
||||||
|
regVal &^= CLKIN_ENABLE
|
||||||
|
}
|
||||||
|
case FANOUT_XO:
|
||||||
|
if enable {
|
||||||
|
regVal |= XTAL_ENABLE
|
||||||
|
} else {
|
||||||
|
regVal &^= XTAL_ENABLE
|
||||||
|
}
|
||||||
|
case FANOUT_MS:
|
||||||
|
if enable {
|
||||||
|
regVal |= MULTISYNTH_ENABLE
|
||||||
|
} else {
|
||||||
|
regVal &^= MULTISYNTH_ENABLE
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return ErrInvalidParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.rw.Write8(FANOUT_ENABLE, regVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetClockSource sets the clock source for a multisynth output.
|
||||||
|
// clk - Clock output (0..7)
|
||||||
|
// src - Clock source (see constants below)
|
||||||
|
func (d *Device) SetClockSource(clk uint8, src uint8) error {
|
||||||
|
if !d.initialised {
|
||||||
|
return ErrNotInitialised
|
||||||
|
}
|
||||||
|
|
||||||
|
clkReg := CLK0_CONTROL + clk
|
||||||
|
regVal, err := d.rw.Read8(clkReg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the input source bits
|
||||||
|
regVal &^= CLK_INPUT_MASK
|
||||||
|
|
||||||
|
switch src {
|
||||||
|
case CLK_SRC_XTAL:
|
||||||
|
regVal |= CLK_INPUT_XTAL
|
||||||
|
case CLK_SRC_CLKIN:
|
||||||
|
regVal |= CLK_INPUT_CLKIN
|
||||||
|
case CLK_SRC_MS0:
|
||||||
|
if clk == 0 {
|
||||||
|
return nil // MS0 not valid for CLK0
|
||||||
|
}
|
||||||
|
regVal |= CLK_INPUT_MULTISYNTH_0_4
|
||||||
|
case CLK_SRC_MS:
|
||||||
|
regVal |= CLK_INPUT_MULTISYNTH_N
|
||||||
|
default:
|
||||||
|
return ErrInvalidParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.rw.Write8(clkReg, regVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetClockInvert enables or disables inversion of the clock output waveform.
|
||||||
|
// clk - Clock output (0..7)
|
||||||
|
// invert - true to enable inversion, false to disable
|
||||||
|
func (d *Device) SetClockInvert(clk uint8, invert bool) error {
|
||||||
|
if !d.initialised {
|
||||||
|
return ErrNotInitialised
|
||||||
|
}
|
||||||
|
|
||||||
|
clkReg := CLK0_CONTROL + clk
|
||||||
|
regVal, err := d.rw.Read8(clkReg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if invert {
|
||||||
|
regVal |= CLK_INVERT
|
||||||
|
} else {
|
||||||
|
regVal &^= CLK_INVERT
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.rw.Write8(clkReg, regVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDriveStrength sets the drive strength of the specified clock output.
|
||||||
|
// clk - Clock output (0..7)
|
||||||
|
// drive - Desired drive level (use SI5351_CLK_DRIVE_STRENGTH_* constants)
|
||||||
|
func (d *Device) SetDriveStrength(clk uint8, drive uint8) error {
|
||||||
|
if !d.initialised {
|
||||||
|
return ErrNotInitialised
|
||||||
|
}
|
||||||
|
|
||||||
|
const mask = 0x03
|
||||||
|
clkReg := CLK0_CONTROL + clk
|
||||||
|
regVal, err := d.rw.Read8(clkReg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear drive strength bits
|
||||||
|
regVal &^= mask
|
||||||
|
|
||||||
|
switch drive {
|
||||||
|
case CLK_DRIVE_STRENGTH_2MA:
|
||||||
|
regVal |= 0x00
|
||||||
|
case CLK_DRIVE_STRENGTH_4MA:
|
||||||
|
regVal |= 0x01
|
||||||
|
case CLK_DRIVE_STRENGTH_6MA:
|
||||||
|
regVal |= 0x02
|
||||||
|
case CLK_DRIVE_STRENGTH_8MA:
|
||||||
|
regVal |= 0x03
|
||||||
|
default:
|
||||||
|
return ErrInvalidParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.rw.Write8(clkReg, regVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetClockPower enables or disables power to a clock output (power saving).
|
||||||
|
// clk - Clock output (0..7)
|
||||||
|
// enable - true to enable power, false to disable (power down)
|
||||||
|
func (d *Device) SetClockPower(clk uint8, enable bool) error {
|
||||||
|
if !d.initialised {
|
||||||
|
return ErrNotInitialised
|
||||||
|
}
|
||||||
|
|
||||||
|
clkReg := CLK0_CONTROL + clk
|
||||||
|
regVal, err := d.rw.Read8(clkReg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if enable {
|
||||||
|
regVal &^= 0x80 // Clear bit 7 to enable power
|
||||||
|
} else {
|
||||||
|
regVal |= 0x80 // Set bit 7 to disable power (power down)
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.rw.Write8(clkReg, regVal)
|
||||||
|
}
|
||||||
|
|||||||
+19
-16
@@ -5,12 +5,13 @@ package st7735 // import "tinygo.org/x/drivers/st7735"
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
"tinygo.org/x/drivers/pixel"
|
"tinygo.org/x/drivers/pixel"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -39,10 +40,10 @@ type Device = DeviceOf[pixel.RGB565BE]
|
|||||||
// formats.
|
// formats.
|
||||||
type DeviceOf[T Color] struct {
|
type DeviceOf[T Color] struct {
|
||||||
bus drivers.SPI
|
bus drivers.SPI
|
||||||
dcPin machine.Pin
|
dcPin pin.OutputFunc
|
||||||
resetPin machine.Pin
|
resetPin pin.OutputFunc
|
||||||
csPin machine.Pin
|
csPin pin.OutputFunc
|
||||||
blPin machine.Pin
|
blPin pin.OutputFunc
|
||||||
width int16
|
width int16
|
||||||
height int16
|
height int16
|
||||||
columnOffset int16
|
columnOffset int16
|
||||||
@@ -65,23 +66,25 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new ST7735 connection. The SPI wire must already be configured.
|
// New creates a new ST7735 connection. The SPI wire must already be configured.
|
||||||
func New(bus drivers.SPI, resetPin, dcPin, csPin, blPin machine.Pin) Device {
|
func New(bus drivers.SPI, resetPin, dcPin, csPin, blPin pin.Output) Device {
|
||||||
return NewOf[pixel.RGB565BE](bus, resetPin, dcPin, csPin, blPin)
|
return NewOf[pixel.RGB565BE](bus, resetPin, dcPin, csPin, blPin)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOf creates a new ST7735 connection with a particular pixel format. The SPI
|
// NewOf creates a new ST7735 connection with a particular pixel format. The SPI
|
||||||
// wire must already be configured.
|
// wire must already be configured.
|
||||||
func NewOf[T Color](bus drivers.SPI, resetPin, dcPin, csPin, blPin machine.Pin) DeviceOf[T] {
|
func NewOf[T Color](bus drivers.SPI, resetPin, dcPin, csPin, blPin pin.Output) DeviceOf[T] {
|
||||||
dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
// IMPORTANT: pin configuration should really be done outside of this driver,
|
||||||
resetPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
// but for backwards compatibility with existing code, we do it here.
|
||||||
csPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(dcPin)
|
||||||
blPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(resetPin)
|
||||||
|
legacy.ConfigurePinOut(csPin)
|
||||||
|
legacy.ConfigurePinOut(blPin)
|
||||||
return DeviceOf[T]{
|
return DeviceOf[T]{
|
||||||
bus: bus,
|
bus: bus,
|
||||||
dcPin: dcPin,
|
dcPin: dcPin.Set,
|
||||||
resetPin: resetPin,
|
resetPin: resetPin.Set,
|
||||||
csPin: csPin,
|
csPin: csPin.Set,
|
||||||
blPin: blPin,
|
blPin: blPin.Set,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,7 +426,7 @@ func (d *DeviceOf[T]) Data(data uint8) {
|
|||||||
|
|
||||||
// Tx sends data to the display
|
// Tx sends data to the display
|
||||||
func (d *DeviceOf[T]) Tx(data []byte, isCommand bool) {
|
func (d *DeviceOf[T]) Tx(data []byte, isCommand bool) {
|
||||||
d.dcPin.Set(!isCommand)
|
d.dcPin(!isCommand)
|
||||||
d.bus.Tx(data, nil)
|
d.bus.Tx(data, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user