diff --git a/examples/lora/lorawan/common/stm32wlx.go b/examples/lora/lorawan/common/stm32wlx.go index f0503e7ed..059ad46c8 100644 --- a/examples/lora/lorawan/common/stm32wlx.go +++ b/examples/lora/lorawan/common/stm32wlx.go @@ -19,7 +19,10 @@ var ( loraRadio *sx126x.Device ) -var spi = machine.SPI3 +var ( + spi = machine.SPI3 + rstPin = machine.NoPin +) func newRadioControl() sx126x.RadioController { return sx126x.NewRadioControl() @@ -27,7 +30,7 @@ func newRadioControl() sx126x.RadioController { // do sx126x setup here func SetupLora() (lora.Radio, error) { - loraRadio = sx126x.New(spi) + loraRadio = sx126x.New(spi, rstPin) loraRadio.SetDeviceType(sx126x.DEVICE_TYPE_SX1262) // Create radio controller for target diff --git a/examples/lora/lorawan/common/sx126x.go b/examples/lora/lorawan/common/sx126x.go index 029a9b9f6..023b8fbf5 100644 --- a/examples/lora/lorawan/common/sx126x.go +++ b/examples/lora/lorawan/common/sx126x.go @@ -23,6 +23,7 @@ var ( spi = machine.SPI0 nssPin, busyPin, dio1Pin = machine.GP17, machine.GP10, machine.GP11 rxPin, txLowPin, txHighPin = machine.GP13, machine.GP12, machine.GP12 + rstPin = machine.GP10 ) func newRadioControl() sx126x.RadioController { @@ -31,7 +32,8 @@ func newRadioControl() sx126x.RadioController { // do sx126x setup here func SetupLora() (lora.Radio, error) { - loraRadio = sx126x.New(spi) + rstPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) + loraRadio = sx126x.New(spi, rstPin) loraRadio.SetDeviceType(sx126x.DEVICE_TYPE_SX1262) // Create radio controller for target diff --git a/examples/sx126x/lora_continuous/lora_continuous.go b/examples/sx126x/lora_continuous/lora_continuous.go index 03d9c5047..e077c2a07 100644 --- a/examples/sx126x/lora_continuous/lora_continuous.go +++ b/examples/sx126x/lora_continuous/lora_continuous.go @@ -20,14 +20,18 @@ func main() { println("# -----------------------------------------") machine.LED.Configure(machine.PinConfig{Mode: machine.PinOutput}) + rstPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) // Create the driver - loraRadio = sx126x.New(spi) + loraRadio = sx126x.New(spi, rstPin) loraRadio.SetDeviceType(sx126x.DEVICE_TYPE_SX1262) // Create radio controller for target loraRadio.SetRadioController(newRadioControl()) + loraRadio.Reset() + time.Sleep(100 * time.Millisecond) + state := loraRadio.DetectDevice() if !state { panic("sx126x not detected. ") diff --git a/examples/sx126x/lora_continuous/radio.go b/examples/sx126x/lora_continuous/radio.go index 865702621..d31a44e25 100644 --- a/examples/sx126x/lora_continuous/radio.go +++ b/examples/sx126x/lora_continuous/radio.go @@ -12,6 +12,7 @@ var ( spi = machine.SPI0 nssPin, busyPin, dio1Pin = machine.GP17, machine.GP10, machine.GP11 rxPin, txLowPin, txHighPin = machine.GP13, machine.GP12, machine.GP12 + rstPin = machine.GP10 ) func newRadioControl() sx126x.RadioController { diff --git a/examples/sx126x/lora_continuous/radio_stm32wl.go b/examples/sx126x/lora_continuous/radio_stm32wl.go index 9da9de52b..082754049 100644 --- a/examples/sx126x/lora_continuous/radio_stm32wl.go +++ b/examples/sx126x/lora_continuous/radio_stm32wl.go @@ -8,7 +8,10 @@ import ( "tinygo.org/x/drivers/sx126x" ) -var spi = machine.SPI3 +var ( + spi = machine.SPI3 + rstPin = machine.NoPin +) func newRadioControl() sx126x.RadioController { return sx126x.NewRadioControl() diff --git a/examples/sx126x/lora_rxtx/lora_rxtx.go b/examples/sx126x/lora_rxtx/lora_rxtx.go index c3e238e9f..d4acf5ae1 100644 --- a/examples/sx126x/lora_rxtx/lora_rxtx.go +++ b/examples/sx126x/lora_rxtx/lora_rxtx.go @@ -27,9 +27,10 @@ func main() { println("\n# TinyGo Lora RX/TX test") println("# ----------------------") machine.LED.Configure(machine.PinConfig{Mode: machine.PinOutput}) + rstPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) // Create the driver - loraRadio = sx126x.New(spi) + loraRadio = sx126x.New(spi, rstPin) loraRadio.SetDeviceType(sx126x.DEVICE_TYPE_SX1262) // Create radio controller for target diff --git a/examples/sx126x/lora_rxtx/radio.go b/examples/sx126x/lora_rxtx/radio.go index 02a1f2434..6aa037cb5 100644 --- a/examples/sx126x/lora_rxtx/radio.go +++ b/examples/sx126x/lora_rxtx/radio.go @@ -12,6 +12,7 @@ var ( spi = machine.SPI1 nssPin, busyPin, dio1Pin = machine.GP13, machine.GP6, machine.GP7 rxPin, txLowPin, txHighPin = machine.GP9, machine.GP8, machine.GP8 + rstPin = machine.GP10 ) func newRadioControl() sx126x.RadioController { diff --git a/examples/sx126x/lora_rxtx/radio_stm32wl.go b/examples/sx126x/lora_rxtx/radio_stm32wl.go index 9da9de52b..082754049 100644 --- a/examples/sx126x/lora_rxtx/radio_stm32wl.go +++ b/examples/sx126x/lora_rxtx/radio_stm32wl.go @@ -8,7 +8,10 @@ import ( "tinygo.org/x/drivers/sx126x" ) -var spi = machine.SPI3 +var ( + spi = machine.SPI3 + rstPin = machine.NoPin +) func newRadioControl() sx126x.RadioController { return sx126x.NewRadioControl() diff --git a/sx126x/radiocontrol_wio_sx1262.go b/sx126x/radiocontrol_wio_sx1262.go new file mode 100644 index 000000000..660e32924 --- /dev/null +++ b/sx126x/radiocontrol_wio_sx1262.go @@ -0,0 +1,28 @@ +//go:build wio_sx1262 + +package sx126x + +import ( + "machine" +) + +// NewRadioControlWio creates RadioControl configured for wio1262 module. +// The board has RF_SW pin which controls RX/TX, but providing it is not required +// if SetDio2AsRfSwitchCtrl is set to true (use machine.NoPin instead). +// Additionally, the board requires following settings on initalization: +/* + radio.SetDio3AsTcxoCtrl(sx126x.SX126X_DIO3_OUTPUT_1_8, 5*time.Millisecond) + radio.SetRegulatorMode(sx126x.SX126X_REGULATOR_DC_DC) + radio.SetDeviceType(sx126x.DEVICE_TYPE_SX1262) + radio.Calibrate(sx126x.SX126X_CALIBRATE_ALL) +*/ +func NewRadioControlWio(nssPin, busyPin, dio1Pin, rfSw machine.Pin) *RadioControl { + return &RadioControl{ + nssPin: nssPin, + busyPin: busyPin, + dio1Pin: dio1Pin, + rxPin: rfSw, + txLowPin: machine.NoPin, + txHighPin: machine.NoPin, + } +} diff --git a/sx126x/registers.go b/sx126x/registers.go index 19b42e19e..1628eef9d 100644 --- a/sx126x/registers.go +++ b/sx126x/registers.go @@ -181,16 +181,6 @@ const ( SX126X_DIO2_AS_IRQ = 0x00 // 7 0 DIO2 configuration: IRQ SX126X_DIO2_AS_RF_SWITCH = 0x01 // 7 0 RF switch control - //SX126X_CMD_SET_DIO3_AS_TCXO_CTRL - SX126X_DIO3_OUTPUT_1_6 = 0x00 // 7 0 DIO3 voltage output for TCXO: 1.6 V - SX126X_DIO3_OUTPUT_1_7 = 0x01 // 7 0 1.7 V - SX126X_DIO3_OUTPUT_1_8 = 0x02 // 7 0 1.8 V - SX126X_DIO3_OUTPUT_2_2 = 0x03 // 7 0 2.2 V - SX126X_DIO3_OUTPUT_2_4 = 0x04 // 7 0 2.4 V - SX126X_DIO3_OUTPUT_2_7 = 0x05 // 7 0 2.7 V - SX126X_DIO3_OUTPUT_3_0 = 0x06 // 7 0 3.0 V - SX126X_DIO3_OUTPUT_3_3 = 0x07 // 7 0 3.3 V - //SX126X_CMD_SET_PACKET_TYPE SX126X_PACKET_TYPE_GFSK = 0x00 // 7 0 packet type: GFSK SX126X_PACKET_TYPE_LORA = 0x01 // 7 0 LoRa @@ -312,3 +302,17 @@ const ( SX126X_LORA_MAC_PUBLIC_SYNCWORD = 0x3444 SX126X_LORA_MAC_PRIVATE_SYNCWORD = 0x1424 ) + +type Dio3OutputVoltage uint8 + +const ( + //SX126X_CMD_SET_DIO3_AS_TCXO_CTRL + SX126X_DIO3_OUTPUT_1_6 Dio3OutputVoltage = 0x00 // 7 0 DIO3 voltage output for TCXO: 1.6 V + SX126X_DIO3_OUTPUT_1_7 Dio3OutputVoltage = 0x01 // 7 0 1.7 V + SX126X_DIO3_OUTPUT_1_8 Dio3OutputVoltage = 0x02 // 7 0 1.8 V + SX126X_DIO3_OUTPUT_2_2 Dio3OutputVoltage = 0x03 // 7 0 2.2 V + SX126X_DIO3_OUTPUT_2_4 Dio3OutputVoltage = 0x04 // 7 0 2.4 V + SX126X_DIO3_OUTPUT_2_7 Dio3OutputVoltage = 0x05 // 7 0 2.7 V + SX126X_DIO3_OUTPUT_3_0 Dio3OutputVoltage = 0x06 // 7 0 3.0 V + SX126X_DIO3_OUTPUT_3_3 Dio3OutputVoltage = 0x07 // 7 0 3.3 V +) diff --git a/sx126x/sx126x.go b/sx126x/sx126x.go index 0cee91b1d..9642da2d0 100644 --- a/sx126x/sx126x.go +++ b/sx126x/sx126x.go @@ -7,9 +7,8 @@ import ( "errors" "time" - "machine" - "tinygo.org/x/drivers" + "tinygo.org/x/drivers/internal/pin" "tinygo.org/x/drivers/lora" ) @@ -42,7 +41,7 @@ const ( // Device wraps an SPI connection to a SX126x device. type Device struct { spi drivers.SPI // SPI bus for module communication - rstPin machine.Pin // GPIO for reset pin + rstPin pin.Output // GPIO for reset pin radioEventChan chan lora.RadioEvent // Channel for Receiving events loraConf lora.Config // Current Lora configuration controller RadioController // to manage interactions with the radio @@ -54,9 +53,10 @@ type Device struct { } // New creates a new SX126x connection. -func New(spi drivers.SPI) *Device { +func New(spi drivers.SPI, rstPin pin.Output) *Device { return &Device{ spi: spi, + rstPin: rstPin, radioEventChan: make(chan lora.RadioEvent, RADIOEVENTCHAN_SIZE), spiTxBuf: make([]byte, SPI_BUFFER_SIZE), spiRxBuf: make([]byte, SPI_BUFFER_SIZE), @@ -108,9 +108,9 @@ func (d *Device) SetRadioController(rc RadioController) error { // -------------------------------------------------- func (d *Device) Reset() { - d.rstPin.Low() + d.rstPin.Set(false) time.Sleep(100 * time.Millisecond) - d.rstPin.High() + d.rstPin.Set(true) time.Sleep(100 * time.Millisecond) } @@ -309,6 +309,33 @@ func (d *Device) SetDioIrqParams(irqMask, dio1Mask, dio2Mask, dio3Mask uint16) { d.ExecSetCommand(SX126X_CMD_SET_DIO_IRQ_PARAMS, p[:]) } +// SetDio2AsRfSwitchCtrl configures if DIO2 is used to control an external RF switch. +// When controlling the external RX switch, the pin DIO2 will toggle according to +// the internal state machine (DIO2 = 0 in SLEEP, STDBY_RX, STDBY_XOSC, FS and RX modes, +// DIO2 = 1 in TX mode). Otherwise DIO2 is free to be used as an IRQ. +func (d *Device) SetDio2AsRfSwitchCtrl(enable bool) { + p := [1]uint8{SX126X_DIO2_AS_IRQ} + if enable { + p[0] = SX126X_DIO2_AS_RF_SWITCH + } + d.ExecSetCommand(SX126X_CMD_SET_DIO2_AS_RF_SWITCH_CTRL, p[:]) +} + +// SetDio3AsTcxoCtrl configures the DIO3 as an external TCXO voltage reference. +// After TCXO control is set, it is recommended to perform full calibration (CALIBRATE_ALL command). +// voltage: output voltage on DIO3 pin +// delay: time for the TCXO to stabilize +func (d *Device) SetDio3AsTcxoCtrl(voltage Dio3OutputVoltage, delay time.Duration) { + timeout := delay / (15625 * time.Nanosecond) + var p [5]uint8 + p[0] = uint8(voltage) + p[1] = uint8((timeout >> 24) & 0xFF) + p[2] = uint8((timeout >> 16) & 0xFF) + p[3] = uint8((timeout >> 8) & 0xFF) + p[4] = uint8((timeout >> 0) & 0xFF) + d.ExecSetCommand(SX126X_CMD_SET_DIO3_AS_TCXO_CTRL, p[:]) +} + // GetIrqStatus returns IRQ status func (d *Device) GetIrqStatus() (irqStatus uint16) { r := d.ExecGetCommand(SX126X_CMD_GET_IRQ_STATUS, 2)