sx127x LoRa example possible deadlock
Steps to recreate
- I've modified the
sx127x.Newfunction to accept adrivers.SPIinstead of amachine.SPI - I've modified the example for the sx127x to run on the pico. See dropdown click box:
What I expected
Forever looping to catch LoRa packets and broadcast packets.
What happened
Program crashes on err := loraRadio.Tx(txmsg, LORA_DEFAULT_TXTIMEOUT_MS). Program stops executing and prints p.
I've tracked the crash to happen during or after this line. I suspect the program deadlocks since it is waiting for an event.
package main
// This example code demonstrates Lora RX/TX With SX127x driver
// You need to connect SPI, RST, CS, DIO0 (aka IRQ) and DIO1 to use.
import (
"machine"
"time"
"tinygo.org/x/drivers/lora"
"tinygo.org/x/drivers/sx127x"
)
const (
LORA_DEFAULT_RXTIMEOUT_MS = 1000
LORA_DEFAULT_TXTIMEOUT_MS = 5000
)
var (
loraRadio *sx127x.Device
txmsg = []byte("Hello TinyGO")
// We assume LoRa Featherwing module is connected to Raspberry Pi Pico:
SX127X_PIN_RST = machine.GP16
SX127X_PIN_DIO0 = machine.GP6
SX127X_PIN_DIO1 = machine.GP7
// SPI definition for SX127x
SX127X_SPI = machine.SPI0
SX127X_PIN_SCK = machine.GP2
SX127X_PIN_TX = machine.GP3
SX127X_PIN_RX = machine.GP4
SX127X_PIN_CS = machine.GP5
)
func dioIrqHandler(machine.Pin) {
loraRadio.HandleInterrupt()
}
func main() {
time.Sleep(5 * time.Second)
println("\n# TinyGo Lora RX/TX test")
println("# ----------------------")
// machine.LED.Configure(machine.PinConfig{Mode: machine.PinOutput})
SX127X_PIN_RST.Configure(machine.PinConfig{Mode: machine.PinOutput})
SX127X_SPI.Configure(machine.SPIConfig{
Frequency: 500000, Mode: 0,
SCK: SX127X_PIN_SCK,
SDO: SX127X_PIN_TX,
SDI: SX127X_PIN_RX,
})
println("main: create and start SX127x driver")
loraRadio = sx127x.New(SX127X_SPI, SX127X_PIN_RST)
loraRadio.SetRadioController(sx127x.NewRadioControl(SX127X_PIN_CS, SX127X_PIN_DIO0, SX127X_PIN_DIO1))
loraRadio.Reset()
state := loraRadio.DetectDevice()
if !state {
panic("main: sx127x NOT FOUND !!!")
} else {
println("main: sx127x found")
}
// Prepare for Lora Operation
loraConf := lora.Config{
Freq: lora.MHz_868_1,
Bw: lora.Bandwidth_125_0,
Sf: lora.SpreadingFactor9,
Cr: lora.CodingRate4_7,
HeaderType: lora.HeaderExplicit,
Preamble: 12,
Iq: lora.IQStandard,
Crc: lora.CRCOn,
SyncWord: lora.SyncPrivate,
LoraTxPowerDBm: 20,
}
loraRadio.LoraConfig(loraConf)
var count uint
for {
tStart := time.Now()
println("main: Receiving Lora for 10 seconds")
for time.Since(tStart) < 10*time.Second {
buf, err := loraRadio.Rx(LORA_DEFAULT_RXTIMEOUT_MS)
if err != nil {
println("RX Error: ", err)
} else if buf != nil {
println("Packet Received: len=", len(buf), string(buf))
}
}
println("main: End Lora RX")
println("LORA TX size=", len(txmsg), " -> ", string(txmsg))
err := loraRadio.Tx(txmsg, LORA_DEFAULT_TXTIMEOUT_MS)
if err != nil {
println("TX Error:", err.Error())
}
count++
}
}
See the tinyglobo repo for a working example.
I have used this board for a couple of talks and demos without problems. @soypat if you have a specific reproducer please do provide.
There is a Details html dropdown in the issue description with the program I used: https://github.com/tinygo-org/drivers/issues/542#issue-1659571633
What hardware did you use for the SX127x? Was it actually the featherwing? In which case, how did you connect the jumpers on the featherwing itself? https://github.com/tinygo-org/drivers/tree/release/sx127x#connecting
Hmm, I'm not sure I understand the RST -> A CS -> B DIO1 -> C IRQ -> D comment. I was using regular commercial SX1278s working at 433MHz. I did the intuitive thing and looked at the code to know where to connect the pins. both DIO0, DIO1, RST, CS, SPI pins. Below is an image of the device used
Using TinyGo 0.28.1 with Pybadge+Featherwing
$ tinygo flash -target pybadge -monitor ./examples/sx127x/lora_rxtx/
Connected to /dev/ttyACM0. Press Ctrl-C to exit.
# TinyGo Lora RX/TX test
# ----------------------
main: create and start SX127x driver
main: sx127x found
main: Receiving Lora for 10 seconds
main: End Lora RX
LORA TX size= 12 -> Hello TinyGO
main: Receiving Lora for 10 seconds
main: End Lora RX
LORA TX size= 12 -> Hello TinyGO
main: Receiving Lora for 10 seconds
main: End Lora RX
LORA TX size= 12 -> Hello TinyGO
main: Receiving Lora for 10 seconds
main: End Lora RX
LORA TX size= 12 -> Hello TinyGO
main: Receiving Lora for 10 seconds
main: End Lora RX
LORA TX size= 12 -> Hello TinyGO
main: Receiving Lora for 10 seconds
This is the code I am running: https://github.com/tinygo-org/drivers/blob/release/examples/sx127x/lora_rxtx/lora_rxtx.go
SX127X_SPI.Configure(machine.SPIConfig{
Frequency: 500000, Mode: 0,
SCK: SX127X_PIN_SCK,
SDO: SX127X_PIN_TX,
SDI: SX127X_PIN_RX,
})
@soypat don't you actually want this?
SDI: SX127X_PIN_TX,
SDO: SX127X_PIN_RX,
don't you actually want this?
Maybe? Not sure. Been a while since I had that setup running.
My current setup has Tx,Rx pins set up correctly and works OK without the gosched() calls introduced in TinyGo 0.28.1