Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sx127x LoRa example possible deadlock #542

Open
soypat opened this issue Apr 8, 2023 · 8 comments
Open

sx127x LoRa example possible deadlock #542

soypat opened this issue Apr 8, 2023 · 8 comments

Comments

@soypat
Copy link
Contributor

soypat commented Apr 8, 2023

Steps to recreate

  • I've modified the sx127x.New function to accept a drivers.SPI instead of a machine.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++
	}

}
@deadprogram
Copy link
Member

See the tinyglobo repo for a working example.

@deadprogram
Copy link
Member

I have used this board for a couple of talks and demos without problems. @soypat if you have a specific reproducer please do provide.

@soypat
Copy link
Contributor Author

soypat commented Jun 7, 2023

There is a Details html dropdown in the issue description with the program I used: #542 (comment)

@deadprogram
Copy link
Member

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

@soypat
Copy link
Contributor Author

soypat commented Jun 9, 2023

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
image

@deadprogram
Copy link
Member

Using TinyGo 0.28.1 with Pybadge+Featherwing

PXL_20230620_210731076

$ 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

@deadprogram
Copy link
Member

        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,

@soypat
Copy link
Contributor Author

soypat commented Jun 25, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants