mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-12 10:53:43 +00:00
sx126x: Driver for Semtech sx126x radio modules and optional RF Switch.
This first version of the driver has been tested with STM32WL SoC, which embeddeds SX1262 radio on the same die.
This commit is contained in:
committed by
Ron Evans
parent
43899e1330
commit
b6c750ccd1
@@ -0,0 +1,80 @@
|
||||
package main
|
||||
|
||||
// This example will periodically enable Continuous "Preamble" and "Wave" modes on 868.1 Mhz
|
||||
import (
|
||||
"machine"
|
||||
"time"
|
||||
|
||||
rfswitch "tinygo.org/x/drivers/examples/sx126x/rfswitch"
|
||||
|
||||
"tinygo.org/x/drivers/sx126x"
|
||||
)
|
||||
|
||||
const FREQ = 868100000
|
||||
|
||||
var (
|
||||
loraRadio *sx126x.Device
|
||||
)
|
||||
|
||||
func main() {
|
||||
println("\n# TinyGo Lora continuous Wave/Preamble test")
|
||||
println("# -----------------------------------------")
|
||||
|
||||
machine.LED.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
|
||||
// Create the driver
|
||||
loraRadio = sx126x.New(machine.SPI3)
|
||||
loraRadio.SetDeviceType(sx126x.DEVICE_TYPE_SX1262)
|
||||
|
||||
// Create RF Switch
|
||||
var radioSwitch rfswitch.CustomSwitch
|
||||
loraRadio.SetRfSwitch(radioSwitch)
|
||||
|
||||
state := loraRadio.DetectDevice()
|
||||
if !state {
|
||||
panic("sx126x not detected. ")
|
||||
}
|
||||
|
||||
// Prepare for Lora operation
|
||||
loraConf := sx126x.LoraConfig{
|
||||
Freq: FREQ,
|
||||
Bw: sx126x.SX126X_LORA_BW_500_0,
|
||||
Sf: sx126x.SX126X_LORA_SF9,
|
||||
Cr: sx126x.SX126X_LORA_CR_4_7,
|
||||
HeaderType: sx126x.SX126X_LORA_HEADER_EXPLICIT,
|
||||
Preamble: 12,
|
||||
Ldr: sx126x.SX126X_LORA_LOW_DATA_RATE_OPTIMIZE_OFF,
|
||||
Iq: sx126x.SX126X_LORA_IQ_STANDARD,
|
||||
Crc: sx126x.SX126X_LORA_CRC_ON,
|
||||
SyncWord: sx126x.SX126X_LORA_MAC_PRIVATE_SYNCWORD,
|
||||
LoraTxPowerDBm: 14,
|
||||
}
|
||||
loraRadio.LoraConfig(loraConf)
|
||||
|
||||
// Although LoraConfig has already configured most of Lora settings,
|
||||
// the following lines are still required to enable Continuous Preamble/Wave
|
||||
loraRadio.SetPacketType(sx126x.SX126X_PACKET_TYPE_LORA)
|
||||
loraRadio.SetRfFrequency(loraConf.Freq)
|
||||
loraRadio.SetModulationParams(loraConf.Sf, loraConf.Bw, loraConf.Cr, loraConf.Ldr)
|
||||
loraRadio.SetTxParams(loraConf.LoraTxPowerDBm, sx126x.SX126X_PA_RAMP_200U)
|
||||
|
||||
for {
|
||||
println("2 seconds in Continuous Preamble")
|
||||
loraRadio.SetStandby()
|
||||
loraRadio.SetTxContinuousPreamble()
|
||||
time.Sleep(2 * time.Second)
|
||||
println("Continuous Preamble Stopped")
|
||||
|
||||
loraRadio.SetStandby()
|
||||
time.Sleep(10 * time.Second)
|
||||
|
||||
println("2 seconds in Continuous Wave")
|
||||
loraRadio.SetTxContinuousWave()
|
||||
time.Sleep(2 * time.Second)
|
||||
println(" Continuous Wave Stopped")
|
||||
|
||||
loraRadio.SetStandby()
|
||||
time.Sleep(60 * time.Second)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package main
|
||||
|
||||
// In this example, a Lora packet will be sent every 10s
|
||||
// module will be in RX mode between two transmissions
|
||||
|
||||
import (
|
||||
"device/stm32"
|
||||
"machine"
|
||||
"runtime/interrupt"
|
||||
"time"
|
||||
|
||||
rfswitch "tinygo.org/x/drivers/examples/sx126x/rfswitch"
|
||||
|
||||
"tinygo.org/x/drivers/sx126x"
|
||||
)
|
||||
|
||||
const FREQ = 868100000
|
||||
|
||||
const (
|
||||
LORA_DEFAULT_RXTIMEOUT_MS = 1000
|
||||
LORA_DEFAULT_TXTIMEOUT_MS = 5000
|
||||
)
|
||||
|
||||
var (
|
||||
loraRadio *sx126x.Device
|
||||
txmsg = []byte("Hello TinyGO")
|
||||
)
|
||||
|
||||
// radioIntHandler will take care of radio interrupts
|
||||
func radioIntHandler(intr interrupt.Interrupt) {
|
||||
loraRadio.HandleInterrupt()
|
||||
}
|
||||
|
||||
func main() {
|
||||
println("\n# TinyGo Lora RX/TX test")
|
||||
println("# ----------------------")
|
||||
machine.LED.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
|
||||
// Create the driver
|
||||
loraRadio = sx126x.New(machine.SPI3)
|
||||
loraRadio.SetDeviceType(sx126x.DEVICE_TYPE_SX1262)
|
||||
|
||||
// Create RF Switch
|
||||
var radioSwitch rfswitch.CustomSwitch
|
||||
loraRadio.SetRfSwitch(radioSwitch)
|
||||
|
||||
// Detect the device
|
||||
state := loraRadio.DetectDevice()
|
||||
if !state {
|
||||
panic("sx126x not detected.")
|
||||
}
|
||||
|
||||
// Add interrupt handler for Radio IRQs
|
||||
intr := interrupt.New(stm32.IRQ_Radio_IRQ_Busy, radioIntHandler)
|
||||
intr.Enable()
|
||||
|
||||
loraConf := sx126x.LoraConfig{
|
||||
Freq: FREQ,
|
||||
Bw: sx126x.SX126X_LORA_BW_500_0,
|
||||
Sf: sx126x.SX126X_LORA_SF9,
|
||||
Cr: sx126x.SX126X_LORA_CR_4_7,
|
||||
HeaderType: sx126x.SX126X_LORA_HEADER_EXPLICIT,
|
||||
Preamble: 12,
|
||||
Ldr: sx126x.SX126X_LORA_LOW_DATA_RATE_OPTIMIZE_OFF,
|
||||
Iq: sx126x.SX126X_LORA_IQ_STANDARD,
|
||||
Crc: sx126x.SX126X_LORA_CRC_ON,
|
||||
SyncWord: sx126x.SX126X_LORA_MAC_PRIVATE_SYNCWORD,
|
||||
LoraTxPowerDBm: 20,
|
||||
}
|
||||
|
||||
loraRadio.LoraConfig(loraConf)
|
||||
|
||||
var count uint
|
||||
for {
|
||||
tStart := time.Now()
|
||||
|
||||
// Blocking RX for LORA_DEFAULT_RXTIMEOUT_MS
|
||||
println("Start Lora RX for 10 sec")
|
||||
for int(time.Now().Sub(tStart).Seconds()) < 10 {
|
||||
buf, err := loraRadio.LoraRx(LORA_DEFAULT_RXTIMEOUT_MS)
|
||||
|
||||
if err != nil {
|
||||
println("RX Error: ", err)
|
||||
} else if buf != nil {
|
||||
println("Packet Received: len=", len(buf), string(buf))
|
||||
}
|
||||
}
|
||||
println("END Lora RX")
|
||||
|
||||
println("LORA TX size=", len(txmsg))
|
||||
err := loraRadio.LoraTx(txmsg, LORA_DEFAULT_TXTIMEOUT_MS)
|
||||
if err != nil {
|
||||
println("TX Error:", err)
|
||||
}
|
||||
count++
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
//go:build gnse
|
||||
// +build gnse
|
||||
|
||||
/*
|
||||
Generic Node Sensor Edition
|
||||
RFSwitch
|
||||
|
||||
Disable Switch : PB8=OFF PA0=OFF PA1=OFF
|
||||
Enable RX : PB8=ON PA0=ON PA1=OFF
|
||||
Enable TX RFO LP : PB8=ON PA0=ON PA1=ON
|
||||
Enable TX RFO HP : PB8=ON PA0=OFF PA1=ON
|
||||
*/
|
||||
package rfswitch
|
||||
|
||||
import (
|
||||
"machine"
|
||||
|
||||
"tinygo.org/x/drivers/sx126x"
|
||||
)
|
||||
|
||||
type CustomSwitch struct {
|
||||
}
|
||||
|
||||
var (
|
||||
rfstate int
|
||||
)
|
||||
|
||||
func (s CustomSwitch) InitRFSwitch() {
|
||||
machine.RF_FE_CTRL1.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
machine.RF_FE_CTRL2.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
machine.RF_FE_CTRL3.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
rfstate = -1 //Unknown
|
||||
}
|
||||
|
||||
func (s CustomSwitch) SetRfSwitchMode(mode int) error {
|
||||
if mode == rfstate {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch mode {
|
||||
|
||||
case sx126x.RFSWITCH_TX_HP:
|
||||
machine.RF_FE_CTRL1.Set(false)
|
||||
machine.RF_FE_CTRL2.Set(true)
|
||||
machine.RF_FE_CTRL3.Set(true)
|
||||
|
||||
case sx126x.RFSWITCH_TX_LP:
|
||||
machine.RF_FE_CTRL1.Set(true)
|
||||
machine.RF_FE_CTRL2.Set(true)
|
||||
machine.RF_FE_CTRL3.Set(true)
|
||||
|
||||
case sx126x.RFSWITCH_RX:
|
||||
machine.RF_FE_CTRL1.Set(true)
|
||||
machine.RF_FE_CTRL2.Set(false)
|
||||
machine.RF_FE_CTRL3.Set(true)
|
||||
}
|
||||
|
||||
rfstate = mode
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
//go:build lorae5
|
||||
// +build lorae5
|
||||
|
||||
package radio
|
||||
|
||||
/*
|
||||
/!\ LoRa-E5 module ONLY transmits through RFO_HP:
|
||||
|
||||
Receive: PA4=1, PA5=0
|
||||
Transmit(high output power, SMPS mode): PA4=0, PA5=1
|
||||
|
||||
*/
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"machine"
|
||||
|
||||
"tinygo.org/x/drivers/sx126x"
|
||||
)
|
||||
|
||||
type CustomSwitch struct {
|
||||
}
|
||||
|
||||
func (s CustomSwitch) InitRFSwitch() {
|
||||
machine.PA4.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
machine.PB5.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
}
|
||||
|
||||
func (s CustomSwitch) SetRfSwitchMode(mode int) error {
|
||||
switch mode {
|
||||
|
||||
case sx126x.RFSWITCH_RX:
|
||||
machine.PA4.Set(true)
|
||||
machine.PB5.Set(false)
|
||||
case sx126x.RFSWITCH_TX_LP:
|
||||
errors.New("RFSWITCH_TX_LP not supported ")
|
||||
case sx126x.RFSWITCH_TX_HP:
|
||||
machine.PA4.Set(false)
|
||||
machine.PB5.Set(true)
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
//go:build nucleowl55jc
|
||||
// +build nucleowl55jc
|
||||
|
||||
/*
|
||||
Nucleo WL55JC1
|
||||
RFSwitch
|
||||
|
||||
+-----------+---------+------------+------------+
|
||||
| | FE_CTRL1 | FE_CTRL2 | FE_CTRL3 |
|
||||
| | (PC4) | (PC5) | (PC3) |
|
||||
+-----------+----------+-----------+------------+
|
||||
| TX_HP | LOW | HIGH | HIGH |
|
||||
| TX_LP | HIGH | HIGH | HIGH |
|
||||
| RX | HIGH | LOW | HIGH |
|
||||
+-----------+----------+-----------+------------+
|
||||
*/
|
||||
package rfswitch
|
||||
|
||||
import (
|
||||
"machine"
|
||||
|
||||
"tinygo.org/x/drivers/sx126x"
|
||||
)
|
||||
|
||||
type CustomSwitch struct {
|
||||
}
|
||||
|
||||
func (s CustomSwitch) InitRFSwitch() {
|
||||
machine.PC4.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
machine.PC5.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
machine.PC3.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
}
|
||||
|
||||
func (s CustomSwitch) SetRfSwitchMode(mode int) error {
|
||||
switch mode {
|
||||
|
||||
case sx126x.RFSWITCH_TX_HP:
|
||||
machine.PC4.Set(false)
|
||||
machine.PC5.Set(true)
|
||||
machine.PC3.Set(true)
|
||||
|
||||
case sx126x.RFSWITCH_TX_LP:
|
||||
machine.PC4.Set(true)
|
||||
machine.PC5.Set(true)
|
||||
machine.PC3.Set(true)
|
||||
|
||||
case sx126x.RFSWITCH_RX:
|
||||
machine.PC4.Set(true)
|
||||
machine.PC5.Set(false)
|
||||
machine.PC3.Set(true)
|
||||
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user