From 4a950a44741523f7d6fe263c146668c4eb867394 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Thu, 26 Jan 2023 21:37:59 +0100 Subject: [PATCH] sx127x: add RadioController interface to match sx126x Signed-off-by: deadprogram --- examples/sx127x/lora_rxtx/lora_rxtx.go | 18 ++------- sx127x/radiocontrol.go | 10 +++++ sx127x/radiocontrol_pins.go | 55 ++++++++++++++++++++++++++ sx127x/sx127x.go | 25 ++++++++---- 4 files changed, 87 insertions(+), 21 deletions(-) create mode 100644 sx127x/radiocontrol.go create mode 100644 sx127x/radiocontrol_pins.go diff --git a/examples/sx127x/lora_rxtx/lora_rxtx.go b/examples/sx127x/lora_rxtx/lora_rxtx.go index 80f8fec..f6269ea 100644 --- a/examples/sx127x/lora_rxtx/lora_rxtx.go +++ b/examples/sx127x/lora_rxtx/lora_rxtx.go @@ -40,13 +40,13 @@ func main() { println("# ----------------------") machine.LED.Configure(machine.PinConfig{Mode: machine.PinOutput}) SX127X_PIN_RST.Configure(machine.PinConfig{Mode: machine.PinOutput}) - SX127X_PIN_CS.Configure(machine.PinConfig{Mode: machine.PinOutput}) - SX127X_PIN_DIO0.Configure(machine.PinConfig{Mode: machine.PinInputPullup}) - SX127X_PIN_DIO1.Configure(machine.PinConfig{Mode: machine.PinInputPullup}) + SX127X_SPI.Configure(machine.SPIConfig{Frequency: 500000, Mode: 0}) println("main: create and start SX127x driver") - loraRadio = sx127x.New(SX127X_SPI, SX127X_PIN_CS, SX127X_PIN_RST) + 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 { @@ -55,16 +55,6 @@ func main() { println("main: sx127x found") } - // Setup DIO0 interrupt Handling - if err := SX127X_PIN_DIO0.SetInterrupt(machine.PinRising, dioIrqHandler); err != nil { - println("could not configure DIO0 pin interrupt:", err.Error()) - } - - // Setup DIO1 interrupt Handling - if err := SX127X_PIN_DIO1.SetInterrupt(machine.PinRising, dioIrqHandler); err != nil { - println("could not configure DIO1 pin interrupt:", err.Error()) - } - // Prepare for Lora Operation loraConf := lora.Config{ Freq: FREQ, diff --git a/sx127x/radiocontrol.go b/sx127x/radiocontrol.go new file mode 100644 index 0000000..a5b04a3 --- /dev/null +++ b/sx127x/radiocontrol.go @@ -0,0 +1,10 @@ +package sx127x + +// SX127X radio transceiver has several pins that control NSS, +// and that are signalled when RX or TX operations are completed. +// This interface allows the creation of types that can control this +type RadioController interface { + Init() error + SetNss(state bool) error + SetupInterrupts(handler func()) error +} diff --git a/sx127x/radiocontrol_pins.go b/sx127x/radiocontrol_pins.go new file mode 100644 index 0000000..231aea8 --- /dev/null +++ b/sx127x/radiocontrol_pins.go @@ -0,0 +1,55 @@ +package sx127x + +import ( + "machine" +) + +// RadioControl for boards that are connected using normal pins. +type RadioControl struct { + nssPin, dio0Pin, dio1Pin machine.Pin +} + +func NewRadioControl(nssPin, dio0Pin, dio1Pin machine.Pin) *RadioControl { + return &RadioControl{ + nssPin: nssPin, + dio0Pin: dio0Pin, + dio1Pin: dio1Pin, + } +} + +// SetNss sets the NSS line aka chip select for SPI. +func (rc *RadioControl) SetNss(state bool) error { + rc.nssPin.Set(state) + return nil +} + +// Init() configures whatever needed for sx127x radio control +func (rc *RadioControl) Init() error { + rc.nssPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) + rc.dio0Pin.Configure(machine.PinConfig{Mode: machine.PinInputPulldown}) + rc.dio1Pin.Configure(machine.PinConfig{Mode: machine.PinInputPulldown}) + return nil +} + +// add interrupt handlers for Radio IRQs for pins +func (rc *RadioControl) SetupInterrupts(handler func()) error { + irqHandler = handler + + // Setup DIO0 interrupt Handling + if err := rc.dio0Pin.SetInterrupt(machine.PinRising, handleInterrupt); err != nil { + return err + } + + // Setup DIO1 interrupt Handling + if err := rc.dio1Pin.SetInterrupt(machine.PinRising, handleInterrupt); err != nil { + return err + } + + return nil +} + +var irqHandler func() + +func handleInterrupt(machine.Pin) { + irqHandler() +} diff --git a/sx127x/sx127x.go b/sx127x/sx127x.go index 5f1bee3..a6c1426 100644 --- a/sx127x/sx127x.go +++ b/sx127x/sx127x.go @@ -21,9 +21,10 @@ const ( // Device wraps an SPI connection to a SX127x device. type Device struct { spi drivers.SPI // SPI bus for module communication - rstPin, csPin machine.Pin // GPIOs for reset and chip select + rstPin machine.Pin // GPIO for reset radioEventChan chan lora.RadioEvent // Channel for Receiving events loraConf lora.Config // Current Lora configuration + controller RadioController // to manage interactions with the radio deepSleep bool // Internal Sleep state deviceType int // sx1261,sx1262,sx1268 (defaults sx1261) spiBuffer [SPI_BUFFER_SIZE]uint8 @@ -41,16 +42,26 @@ func (d *Device) GetRadioEventChan() chan lora.RadioEvent { } // New creates a new SX127x connection. The SPI bus must already be configured. -func New(spi machine.SPI, csPin machine.Pin, rstPin machine.Pin) *Device { +func New(spi machine.SPI, rstPin machine.Pin) *Device { k := Device{ spi: spi, - csPin: csPin, rstPin: rstPin, radioEventChan: make(chan lora.RadioEvent, 10), } return &k } +// SetRadioControl let you define the RadioController +func (d *Device) SetRadioController(rc RadioController) error { + d.controller = rc + if err := d.controller.Init(); err != nil { + return err + } + d.controller.SetupInterrupts(d.HandleInterrupt) + + return nil +} + // Reset re-initialize the sx127x device func (d *Device) Reset() { d.rstPin.Low() @@ -67,21 +78,21 @@ func (d *Device) DetectDevice() bool { // ReadRegister reads register value func (d *Device) ReadRegister(reg uint8) uint8 { - d.csPin.Low() + d.controller.SetNss(false) d.spi.Tx([]byte{reg & 0x7f}, nil) var value [1]byte d.spi.Tx(nil, value[:]) - d.csPin.High() + d.controller.SetNss(true) return value[0] } // WriteRegister writes value to register func (d *Device) WriteRegister(reg uint8, value uint8) uint8 { var response [1]byte - d.csPin.Low() + d.controller.SetNss(false) d.spi.Tx([]byte{reg | 0x80}, nil) d.spi.Tx([]byte{value}, response[:]) - d.csPin.High() + d.controller.SetNss(true) return response[0] }