From f15eec822fb91c492add974467b4c85cef5342cb Mon Sep 17 00:00:00 2001 From: Olivier Fauchon Date: Wed, 2 Feb 2022 01:18:24 +0100 Subject: [PATCH] sx127x: Ajout du support d'interruptions RXTimeout (DIO1) --- examples/sx127x/lora_rxtx/lora_rxtx.go | 70 +++++++++++++++++--------- sx127x/registers.go | 3 ++ sx127x/sx127x.go | 32 ++++++------ 3 files changed, 62 insertions(+), 43 deletions(-) diff --git a/examples/sx127x/lora_rxtx/lora_rxtx.go b/examples/sx127x/lora_rxtx/lora_rxtx.go index dcc45d5..f2aa6b2 100644 --- a/examples/sx127x/lora_rxtx/lora_rxtx.go +++ b/examples/sx127x/lora_rxtx/lora_rxtx.go @@ -1,7 +1,7 @@ package main -// This example code demonstrates Lora RX/TX. -// It has been tested with bluepill and SX1276 (RFM95W board) +// This example code demonstrates Lora RX/TX With SX127x driver +// You need to connect SPI, DIO0 and DIO1 to use. import ( "machine" @@ -11,9 +11,10 @@ import ( ) const ( - FREQ = 868100000 LORA_DEFAULT_RXTIMEOUT_MS = 1000 LORA_DEFAULT_TXTIMEOUT_MS = 5000 + + DIO_PIN_CHANGE = machine.PinRising ) var ( @@ -23,27 +24,37 @@ var ( SX127X_PIN_RST = machine.PB9 SX127X_PIN_CS = machine.PB8 SX127X_PIN_DIO0 = machine.PA0 + SX127X_PIN_DIO1 = machine.PA1 SX127X_SPI = machine.SPI0 txmsg = []byte("Hello TinyGO") + + // Prepare for Lora Operation + loraConf = sx127x.LoraConfig{ + Freq: 868100000, + Bw: sx127x.SX127X_LORA_BW_125_0, + Sf: sx127x.SX127X_LORA_SF9, + Cr: sx127x.SX127X_LORA_CR_4_7, + HeaderType: sx127x.SX127X_LORA_HEADER_EXPLICIT, + Preamble: 12, + Iq: sx127x.SX127X_LORA_IQ_STANDARD, + Crc: sx127x.SX127X_LORA_CRC_ON, + SyncWord: sx127x.SX127X_LORA_MAC_PUBLIC_SYNCWORD, + LoraTxPowerDBm: 20, + } ) func main() { - println("\n# TinyGo Lora continuous Wave/Preamble test") - println("# -----------------------------------------") + println("\n# TinyGo Driver SX127X RX/TX example") + println("# ------------------------------------") println("main: configuring LED/SPI/DIO/IRQ") 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.PinInputPulldown}) + 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}) - err := SX127X_PIN_DIO0.SetInterrupt(machine.PinRising, func(machine.Pin) { // Int handler - loraRadio.HandleInterrupt() - }) - if err != nil { - panic("main: Can't configure DIO int handler") - } println("main: create and start SX127x driver") loraRadio = sx127x.New(SX127X_SPI, SX127X_PIN_CS, SX127X_PIN_RST) @@ -55,18 +66,28 @@ func main() { println("main: sx127x found") } + // Setup DIO0 interrupt Handling + err := SX127X_PIN_DIO0.SetInterrupt(DIO_PIN_CHANGE, func(machine.Pin) { + if SX127X_PIN_DIO0.Get() { + loraRadio.HandleInterrupt() + } + }) + if err != nil { + println("could not configure DIO0 pin interrupt:", err.Error()) + } + + // Setup DIO1 interrupt Handling + err = SX127X_PIN_DIO1.SetInterrupt(DIO_PIN_CHANGE, func(machine.Pin) { + if SX127X_PIN_DIO1.Get() { + loraRadio.HandleInterrupt() + } + }) + if err != nil { + println("could not configure DIO1 pin interrupt:", err.Error()) + } + println("main: Configure lora modulation") - loraRadio.SetOpModeLora() - loraRadio.SetOpMode(sx127x.SX127X_OPMODE_SLEEP) - loraRadio.SetTxPower(11, true) - loraRadio.SetLoraFrequency(FREQ) - loraRadio.SetLoraBandwidth(sx127x.SX127X_LORA_BW_125_0) - loraRadio.SetLoraSpreadingFactor(sx127x.SX127X_LORA_SF11) - loraRadio.SetLoraCodingRate(sx127x.SX127X_LORA_CR_4_5) - loraRadio.SetLoraIqMode(sx127x.SX127X_LORA_IQ_STANDARD) - loraRadio.SetLoraCrc(true) - loraRadio.SetLoraHeaderMode(sx127x.SX127X_LORA_HEADER_EXPLICIT) - loraRadio.SetLowDataRateOptim(sx127x.SX127X_LOW_DATARATE_OPTIM_OFF) + loraRadio.LoraConfig(loraConf) // Get uint32 from RSSI rand32 := loraRadio.RandomU32() @@ -78,7 +99,7 @@ func main() { machine.LED.Set(!machine.LED.Get()) println("main: Receiving Lora for 10 seconds") - for int(time.Now().Sub(tStart).Seconds()) < 60 { + for int(time.Now().Sub(tStart).Seconds()) < 10 { buf, err := loraRadio.LoraRx(LORA_DEFAULT_RXTIMEOUT_MS) if err != nil { println("RX Error: ", err) @@ -87,7 +108,6 @@ func main() { } } println("main: End Lora RX") - println("LORA TX size=", len(txmsg), " -> ", string(txmsg)) err := loraRadio.LoraTx(txmsg, LORA_DEFAULT_TXTIMEOUT_MS) if err != nil { diff --git a/sx127x/registers.go b/sx127x/registers.go index 4df39b5..98a2093 100644 --- a/sx127x/registers.go +++ b/sx127x/registers.go @@ -120,4 +120,7 @@ const ( SX127X_OPMODE_RX = uint8(0x05) SX127X_OPMODE_RX_SINGLE = uint8(0x06) SX127X_OPMODE_CAD = uint8(0x07) + + SX127X_LORA_MAC_PUBLIC_SYNCWORD = 0x34 + SX127X_LORA_MAC_PRIVATE_SYNCWORD = 0x14 ) diff --git a/sx127x/sx127x.go b/sx127x/sx127x.go index 361d56e..342f633 100644 --- a/sx127x/sx127x.go +++ b/sx127x/sx127x.go @@ -381,14 +381,14 @@ func (d *Device) LoraTx(pkt []uint8, timeoutMs uint32) error { d.WriteRegister(SX127X_REG_LNA, SX127X_LNA_MAX_GAIN) // Set Low Noise Amplifier to MAX d.SetLoraFrequency(d.loraConf.Freq) - d.SetLoraPreamble(d.loraConf.Preamble) //OK - d.SetLoraSyncWord(d.loraConf.SyncWord) // Should be ok - d.SetLoraBandwidth(d.loraConf.Bw) // OK - d.SetLoraSpreadingFactor(d.loraConf.Sf) // OK - d.SetLoraIqMode(d.loraConf.Iq) //OK + d.SetLoraPreamble(d.loraConf.Preamble) + d.SetLoraSyncWord(d.loraConf.SyncWord) + d.SetLoraBandwidth(d.loraConf.Bw) + d.SetLoraSpreadingFactor(d.loraConf.Sf) + d.SetLoraIqMode(d.loraConf.Iq) d.SetLoraCodingRate(d.loraConf.Cr) d.SetLoraCrc(d.loraConf.Crc == SX127X_LORA_CRC_ON) - d.SetTxPower(10, true) + d.SetTxPower(d.loraConf.LoraTxPowerDBm, true) d.SetLoraHeaderMode(d.loraConf.HeaderType) d.SetAgcAuto(SX127X_AGC_AUTO_ON) @@ -417,7 +417,7 @@ func (d *Device) LoraTx(pkt []uint8, timeoutMs uint32) error { msg := <-d.GetRadioEventChan() if msg.EventType != RadioEventTxDone { - return errors.New("Unexpected Radio Event while TX") + return errors.New("Unexpected Radio Event while TX " + string(0x30+msg.EventType)) } return nil } @@ -445,31 +445,27 @@ func (d *Device) LoraRx(timeoutMs uint32) ([]uint8, error) { d.SetLoraIqMode(d.loraConf.Iq) //OK d.SetLoraCodingRate(d.loraConf.Cr) d.SetLoraCrc(d.loraConf.Crc == SX127X_LORA_CRC_ON) - d.SetTxPower(10, true) + d.SetTxPower(d.loraConf.LoraTxPowerDBm, true) d.SetLoraHeaderMode(d.loraConf.HeaderType) d.SetAgcAuto(SX127X_AGC_AUTO_ON) - // set the IRQ mapping DIO0=TxDone DIO1=NOP DIO2=NOP - d.WriteRegister(SX127X_REG_DIO_MAPPING_1, SX127X_MAP_DIO0_LORA_RXDONE|SX127X_MAP_DIO1_LORA_NOP|SX127X_MAP_DIO2_LORA_NOP) + // set the IRQ mapping DIO0=RxDone DIO1=RxTimeout DIO2=NOP + d.WriteRegister(SX127X_REG_DIO_MAPPING_1, SX127X_MAP_DIO0_LORA_RXDONE|SX127X_MAP_DIO1_LORA_RXTOUT|SX127X_MAP_DIO2_LORA_NOP) // Clear all radio IRQ Flags d.WriteRegister(SX127X_REG_IRQ_FLAGS, 0xFF) - // Mask all but TxDone - d.WriteRegister(SX127X_REG_IRQ_FLAGS_MASK, ^SX127X_IRQ_LORA_RXDONE_MASK) + // Mask all but RxDone + d.WriteRegister(SX127X_REG_IRQ_FLAGS_MASK, ^(SX127X_IRQ_LORA_RXDONE_MASK | SX127X_IRQ_LORA_RXTOUT_MASK)) // Switch to RX Mode - d.SetOpMode(SX127X_OPMODE_RX) + d.SetOpMode(SX127X_OPMODE_RX_SINGLE) // // Wait for Radio Event radioCh := d.GetRadioEventChan() - go func() { - time.Sleep(time.Millisecond * time.Duration(timeoutMs)) - radioCh <- NewRadioEvent(RadioEventTimeout, SX127X_IRQ_LORA_RXTOUT_MASK, nil) - }() msg := <-radioCh if msg.EventType == RadioEventTimeout { return nil, nil } else if msg.EventType != RadioEventRxDone { - return nil, errors.New("Unexpected Radio Event while RX") + return nil, errors.New("Unexpected Radio Event while RX " + string(0x30+msg.EventType)) } d.WriteRegister(SX127X_REG_FIFO_RX_BASE_ADDR, 0)