From fa0cf6ec7fb89a6b30a7822c69a7fa75db5d5f95 Mon Sep 17 00:00:00 2001 From: Olivier Fauchon Date: Mon, 30 Jan 2023 16:50:24 +0100 Subject: [PATCH] lorawan cleanup and optimizations: - Remove all default loraconf default initialisation in lorawan examples (Region Settings takes care of this now) - Remove retries while receiving JoinAccept and increase LoraRX to 10s (no need to wait more than 10s) - Add constants for RegionSetting default frequencies - Standardize all lora default configurations in lora examples - Add new AT+LW=NET,(ON|OFF) command in atcmd example --- examples/lora/lorawan/atcmd/README.md | 11 ++++++ examples/lora/lorawan/atcmd/commands.go | 13 +++++++ .../lora/lorawan/basic-demo/keys-default.go | 6 +++ examples/lora/lorawan/basic-demo/main.go | 18 +-------- examples/lora/lorawan/common/stm32wlx.go | 16 -------- examples/lora/lorawan/common/sx126x.go | 16 -------- examples/lora/lorawan/common/sx127x.go | 16 -------- examples/sx126x/lora_rxtx/lora_rxtx.go | 6 +-- examples/sx127x/lora_rxtx/lora_rxtx.go | 6 +-- lora/config.go | 7 ++++ lora/lorawan/adaptor.go | 38 +++++++++++-------- lora/lorawan/region/au915.go | 6 +-- lora/lorawan/region/eu868.go | 6 +-- lora/radio.go | 3 ++ sx126x/sx126x.go | 6 +++ sx127x/sx127x.go | 17 +++++---- 16 files changed, 89 insertions(+), 102 deletions(-) diff --git a/examples/lora/lorawan/atcmd/README.md b/examples/lora/lorawan/atcmd/README.md index 8fc57e0..af028c1 100644 --- a/examples/lora/lorawan/atcmd/README.md +++ b/examples/lora/lorawan/atcmd/README.md @@ -39,3 +39,14 @@ Builds/flashes atcmd console application on Lora-E5 using onboard SX126x. tinygo flash -target lorae5 ./examples/lora/lorawan/atcmd/ ``` +## Joining a Public Lorawan Network + +``` +AT+ID=DevEui,0101010101010101 +AT+ID=AppEui,0123012301230213 +AT+KEY=APPKEY,AEAEAEAEAEAEAEAAEAEAEAEAEAEAAEAE +AT+LW=NET,ON +AT+JOIN +``` + +AT+LW=NET,(ON|OFF) command changes Lora Sync Word to connect on public network(ON) or private networks(OFF) diff --git a/examples/lora/lorawan/atcmd/commands.go b/examples/lora/lorawan/atcmd/commands.go index 98567b6..1ebcdf9 100644 --- a/examples/lora/lorawan/atcmd/commands.go +++ b/examples/lora/lorawan/atcmd/commands.go @@ -337,6 +337,19 @@ func delay(setting string) error { func lw(setting string) error { cmd := "LW" + + param, val, hasComma := strings.Cut(setting, ",") + if hasComma { + if param == "NET" { + if val == "ON" { + lorawan.SetPublicNetwork(true) + println("SET PUBLIC NET") + } else { + lorawan.SetPublicNetwork(false) + println("SET PRIVATE NET") + } + } + } writeCommandOutput(cmd, setting) return nil diff --git a/examples/lora/lorawan/basic-demo/keys-default.go b/examples/lora/lorawan/basic-demo/keys-default.go index 8728c85..b45e7b5 100644 --- a/examples/lora/lorawan/basic-demo/keys-default.go +++ b/examples/lora/lorawan/basic-demo/keys-default.go @@ -2,10 +2,16 @@ package main +import ( + "tinygo.org/x/drivers/lora/lorawan" +) + // These are sample keys, so the example builds // Either change here, or create a new go file and use customkeys build tag func setLorawanKeys() { otaa.SetAppEUI([]uint8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) otaa.SetDevEUI([]uint8{0xB3, 0xD5, 0x41, 0x00, 0x0A, 0xF1, 0xA4, 0x45}) otaa.SetAppKey([]uint8{0x12, 0x22, 0xA3, 0xFF, 0x0C, 0x7B, 0x76, 0x7B, 0x8F, 0xD3, 0x12, 0x4F, 0xCE, 0x7A, 0x32, 0x16}) + lorawan.SetPublicNetwork(true) + } diff --git a/examples/lora/lorawan/basic-demo/main.go b/examples/lora/lorawan/basic-demo/main.go index 928799a..b42a16a 100644 --- a/examples/lora/lorawan/basic-demo/main.go +++ b/examples/lora/lorawan/basic-demo/main.go @@ -65,28 +65,12 @@ func main() { session = &lorawan.Session{} otaa = &lorawan.Otaa{} - // Initial Lora modulation configuration - loraConf := lora.Config{ - Freq: 868100000, - Bw: lora.Bandwidth_125_0, - Sf: lora.SpreadingFactor9, - Cr: lora.CodingRate4_7, - HeaderType: lora.HeaderExplicit, - Preamble: 12, - Ldr: lora.LowDataRateOptimizeOff, - Iq: lora.IQStandard, - Crc: lora.CRCOn, - SyncWord: lora.SyncPublic, - LoraTxPowerDBm: 20, - } - radio.LoraConfig(loraConf) - // Connect the lorawan with the Lora Radio device. lorawan.UseRadio(radio) lorawan.UseRegionSettings(region.EU868()) - // Configure AppEUI, DevEUI, APPKey + // Configure AppEUI, DevEUI, APPKey, and public/private Lorawan Network setLorawanKeys() if debug != "" { diff --git a/examples/lora/lorawan/common/stm32wlx.go b/examples/lora/lorawan/common/stm32wlx.go index 8b8461b..f0503e7 100644 --- a/examples/lora/lorawan/common/stm32wlx.go +++ b/examples/lora/lorawan/common/stm32wlx.go @@ -37,22 +37,6 @@ func SetupLora() (lora.Radio, error) { return nil, errRadioNotFound } - loraConf := lora.Config{ - Freq: FREQ, - Bw: lora.Bandwidth_500_0, - Sf: lora.SpreadingFactor9, - Cr: lora.CodingRate4_7, - HeaderType: lora.HeaderExplicit, - Preamble: 12, - Ldr: lora.LowDataRateOptimizeOff, - Iq: lora.IQStandard, - Crc: lora.CRCOn, - SyncWord: lora.SyncPrivate, - LoraTxPowerDBm: 20, - } - - loraRadio.LoraConfig(loraConf) - return loraRadio, nil } diff --git a/examples/lora/lorawan/common/sx126x.go b/examples/lora/lorawan/common/sx126x.go index 5d22d6e..029a9b9 100644 --- a/examples/lora/lorawan/common/sx126x.go +++ b/examples/lora/lorawan/common/sx126x.go @@ -41,22 +41,6 @@ func SetupLora() (lora.Radio, error) { return nil, errRadioNotFound } - loraConf := lora.Config{ - Freq: FREQ, - Bw: lora.Bandwidth_500_0, - Sf: lora.SpreadingFactor9, - Cr: lora.CodingRate4_7, - HeaderType: lora.HeaderExplicit, - Preamble: 12, - Ldr: lora.LowDataRateOptimizeOff, - Iq: lora.IQStandard, - Crc: lora.CRCOn, - SyncWord: lora.SyncPrivate, - LoraTxPowerDBm: 20, - } - - loraRadio.LoraConfig(loraConf) - return loraRadio, nil } diff --git a/examples/lora/lorawan/common/sx127x.go b/examples/lora/lorawan/common/sx127x.go index 5bef412..5cffe7e 100644 --- a/examples/lora/lorawan/common/sx127x.go +++ b/examples/lora/lorawan/common/sx127x.go @@ -34,22 +34,6 @@ func SetupLora() (lora.Radio, error) { return nil, errRadioNotFound } - // Prepare for Lora Operation - loraConf := lora.Config{ - Freq: FREQ, - 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.SyncPublic, - LoraTxPowerDBm: 20, - } - - loraRadio.LoraConfig(loraConf) - return loraRadio, nil } diff --git a/examples/sx126x/lora_rxtx/lora_rxtx.go b/examples/sx126x/lora_rxtx/lora_rxtx.go index f382dd3..c3e238e 100644 --- a/examples/sx126x/lora_rxtx/lora_rxtx.go +++ b/examples/sx126x/lora_rxtx/lora_rxtx.go @@ -11,8 +11,6 @@ import ( "tinygo.org/x/drivers/sx126x" ) -const FREQ = 868100000 - const ( LORA_DEFAULT_RXTIMEOUT_MS = 1000 LORA_DEFAULT_TXTIMEOUT_MS = 5000 @@ -44,8 +42,8 @@ func main() { } loraConf := lora.Config{ - Freq: FREQ, - Bw: lora.Bandwidth_500_0, + Freq: lora.MHz_868_1, + Bw: lora.Bandwidth_125_0, Sf: lora.SpreadingFactor9, Cr: lora.CodingRate4_7, HeaderType: lora.HeaderExplicit, diff --git a/examples/sx127x/lora_rxtx/lora_rxtx.go b/examples/sx127x/lora_rxtx/lora_rxtx.go index f6269ea..7d834ca 100644 --- a/examples/sx127x/lora_rxtx/lora_rxtx.go +++ b/examples/sx127x/lora_rxtx/lora_rxtx.go @@ -11,8 +11,6 @@ import ( "tinygo.org/x/drivers/sx127x" ) -const FREQ = 868100000 - const ( LORA_DEFAULT_RXTIMEOUT_MS = 1000 LORA_DEFAULT_TXTIMEOUT_MS = 5000 @@ -57,8 +55,8 @@ func main() { // Prepare for Lora Operation loraConf := lora.Config{ - Freq: FREQ, - Bw: lora.Bandwidth_500_0, + Freq: lora.MHz_868_1, + Bw: lora.Bandwidth_125_0, Sf: lora.SpreadingFactor9, Cr: lora.CodingRate4_7, HeaderType: lora.HeaderExplicit, diff --git a/lora/config.go b/lora/config.go index fa3fe9e..7dd40d1 100644 --- a/lora/config.go +++ b/lora/config.go @@ -76,3 +76,10 @@ const ( SyncPublic = iota SyncPrivate ) + +const ( + MHz_868_1 = 868100000 + MHz_868_5 = 868500000 + MHz_916_8 = 916800000 + MHz_923_3 = 923300000 +) \ No newline at end of file diff --git a/lora/lorawan/adaptor.go b/lora/lorawan/adaptor.go index 98a08f4..803b403 100644 --- a/lora/lorawan/adaptor.go +++ b/lora/lorawan/adaptor.go @@ -24,7 +24,7 @@ var ( const ( LORA_TX_TIMEOUT = 2000 - LORA_RX_TIMEOUT = 5000 + LORA_RX_TIMEOUT = 10000 ) var ( @@ -33,10 +33,12 @@ var ( regionSettings region.RegionSettings ) +// UseRegionSettings sets current Lorawan Regional parameters func UseRegionSettings(rs region.RegionSettings) { regionSettings = rs } +// UseRadio attaches Lora radio driver to Lorawan func UseRadio(r lora.Radio) { if ActiveRadio != nil { panic("lorawan.ActiveRadio is already set") @@ -44,15 +46,25 @@ func UseRadio(r lora.Radio) { ActiveRadio = r } -func ApplyChannelConfig(ch *region.Channel) { +// SetPublicNetwork defines Lora Sync Word according to network type (public/private) +func SetPublicNetwork(enabled bool) { + ActiveRadio.SetPublicNetwork(enabled) +} + +// ApplyChannelConfig sets current Lora modulation according to current regional settings +func applyChannelConfig(ch *region.Channel) { ActiveRadio.SetFrequency(ch.Frequency) ActiveRadio.SetBandwidth(ch.Bandwidth) ActiveRadio.SetCodingRate(ch.CodingRate) ActiveRadio.SetSpreadingFactor(ch.SpreadingFactor) ActiveRadio.SetPreambleLength(ch.PreambleLength) ActiveRadio.SetTxPower(ch.TxPowerDBm) + // Lorawan defaults to explicit headers + ActiveRadio.SetHeaderType(lora.HeaderExplicit) + ActiveRadio.SetCrc(true) } +// Join tries to connect Lorawan Gateway func Join(otaa *Otaa, session *Session) error { var resp []uint8 @@ -73,8 +85,7 @@ func Join(otaa *Otaa, session *Session) error { } // Prepare radio for Join Tx - ApplyChannelConfig(regionSettings.JoinRequestChannel()) - ActiveRadio.SetCrc(true) + applyChannelConfig(regionSettings.JoinRequestChannel()) ActiveRadio.SetIqMode(lora.IQStandard) ActiveRadio.Tx(payload, LORA_TX_TIMEOUT) if err != nil { @@ -82,18 +93,13 @@ func Join(otaa *Otaa, session *Session) error { } // Wait for JoinAccept - ApplyChannelConfig(regionSettings.JoinAcceptChannel()) - ActiveRadio.SetCrc(true) + applyChannelConfig(regionSettings.JoinAcceptChannel()) ActiveRadio.SetIqMode(lora.IQInverted) - for i := 0; i < Retries; i++ { - resp, err = ActiveRadio.Rx(LORA_RX_TIMEOUT) - if err != nil { - return err - } - if resp != nil { - break - } + resp, err = ActiveRadio.Rx(LORA_RX_TIMEOUT) + if err != nil { + return err } + if resp == nil { return ErrNoJoinAcceptReceived } @@ -106,6 +112,7 @@ func Join(otaa *Otaa, session *Session) error { return nil } +// SendUplink sends Lorawan Uplink message func SendUplink(data []uint8, session *Session) error { if regionSettings == nil { @@ -117,8 +124,7 @@ func SendUplink(data []uint8, session *Session) error { return err } - ApplyChannelConfig(regionSettings.UplinkChannel()) - ActiveRadio.SetCrc(true) + applyChannelConfig(regionSettings.UplinkChannel()) ActiveRadio.SetIqMode(lora.IQStandard) ActiveRadio.Tx(payload, LORA_TX_TIMEOUT) if err != nil { diff --git a/lora/lorawan/region/au915.go b/lora/lorawan/region/au915.go index 6cabd4a..a238265 100644 --- a/lora/lorawan/region/au915.go +++ b/lora/lorawan/region/au915.go @@ -15,19 +15,19 @@ type RegionSettingsAU915 struct { func AU915() *RegionSettingsAU915 { return &RegionSettingsAU915{ - joinRequestChannel: &Channel{916800000, + joinRequestChannel: &Channel{lora.MHz_916_8, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_7, AU915_DEFAULT_PREAMBLE_LEN, AU915_DEFAULT_TX_POWER_DBM}, - joinAcceptChannel: &Channel{923300000, + joinAcceptChannel: &Channel{lora.MHz_923_3, lora.Bandwidth_500_0, lora.SpreadingFactor9, lora.CodingRate4_7, AU915_DEFAULT_PREAMBLE_LEN, AU915_DEFAULT_TX_POWER_DBM}, - uplinkChannel: &Channel{868500000, + uplinkChannel: &Channel{lora.MHz_868_5, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_7, diff --git a/lora/lorawan/region/eu868.go b/lora/lorawan/region/eu868.go index 71850e5..f479080 100644 --- a/lora/lorawan/region/eu868.go +++ b/lora/lorawan/region/eu868.go @@ -15,19 +15,19 @@ type RegionSettingsEU868 struct { func EU868() *RegionSettingsEU868 { return &RegionSettingsEU868{ - joinRequestChannel: &Channel{868100000, + joinRequestChannel: &Channel{lora.MHz_868_1, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_7, EU868_DEFAULT_PREAMBLE_LEN, EU868_DEFAULT_TX_POWER_DBM}, - joinAcceptChannel: &Channel{868100000, + joinAcceptChannel: &Channel{lora.MHz_868_1, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_7, EU868_DEFAULT_PREAMBLE_LEN, EU868_DEFAULT_TX_POWER_DBM}, - uplinkChannel: &Channel{868100000, + uplinkChannel: &Channel{lora.MHz_868_1, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_7, diff --git a/lora/radio.go b/lora/radio.go index 97f6b49..110e52e 100644 --- a/lora/radio.go +++ b/lora/radio.go @@ -12,5 +12,8 @@ type Radio interface { SetSpreadingFactor(sf uint8) SetPreambleLength(plen uint16) SetTxPower(txpow int8) + SetSyncWord(syncWord uint16) + SetPublicNetwork(enable bool) + SetHeaderType(headerType uint8) LoraConfig(cnf Config) } diff --git a/sx126x/sx126x.go b/sx126x/sx126x.go index 191a950..653c715 100644 --- a/sx126x/sx126x.go +++ b/sx126x/sx126x.go @@ -576,6 +576,12 @@ func (d *Device) SetTxPower(txpow int8) { d.loraConf.LoraTxPowerDBm = txpow } +// SetHeaderType sets implicit or explicit header mode +// NB: Change will be applied at next RX / TX +func (d *Device) SetHeaderType(headerType uint8) { + d.loraConf.HeaderType = headerType +} + // // Lora functions // diff --git a/sx127x/sx127x.go b/sx127x/sx127x.go index fae572c..982c124 100644 --- a/sx127x/sx127x.go +++ b/sx127x/sx127x.go @@ -276,8 +276,8 @@ func (d *Device) SetCodingRate(cr uint8) { d.WriteRegister(SX127X_REG_MODEM_CONFIG_1, (d.ReadRegister(SX127X_REG_MODEM_CONFIG_1)&0xf1)|(cr<<1)) } -// SetImplicitHeaderModeOn Enables implicit header mode *** -func (d *Device) SetHeaderMode(headerType uint8) { +// SetHeaderType set implicit or explicit mode +func (d *Device) SetHeaderType(headerType uint8) { d.loraConf.HeaderType = headerType if headerType == lora.HeaderImplicit { d.WriteRegister(SX127X_REG_MODEM_CONFIG_1, d.ReadRegister(SX127X_REG_MODEM_CONFIG_1)|0x01) @@ -346,6 +346,14 @@ func (d *Device) SetIqMode(val uint8) { d.WriteRegister(SX127X_REG_INVERTIQ2, 0x19) } } +// SetPublicNetwork changes Sync Word to match network type +func (d *Device) SetPublicNetwork(enabled bool) { + if enabled { + d.SetSyncWord(SX127X_LORA_MAC_PUBLIC_SYNCWORD) + } else { + d.SetSyncWord(SX127X_LORA_MAC_PRIVATE_SYNCWORD) + } + // Tx sends a lora packet, (with timeout) func (d *Device) Tx(pkt []uint8, timeoutMs uint32) error { @@ -538,9 +546,4 @@ func bandwidth(bw uint8) uint8 { } } -func syncword(sw int) uint16 { - if sw == lora.SyncPublic { - return SX127X_LORA_MAC_PUBLIC_SYNCWORD - } - return SX127X_LORA_MAC_PRIVATE_SYNCWORD }