From 4e27854166b0138e845717c2c2e110bf7a43effe Mon Sep 17 00:00:00 2001 From: Mirac Kara Date: Tue, 26 Sep 2023 17:02:18 -0700 Subject: [PATCH 1/6] LoRa WAN US915 Support Adds a driver for us 915 protocol to the lora WAN drivers. --- lora/config.go | 3 + lora/lorawan/adaptor.go | 56 +++++++++------- lora/lorawan/region/au915.go | 43 +++++++++--- lora/lorawan/region/eu868.go | 39 ++++++++--- lora/lorawan/region/regionset.go | 23 +++---- lora/lorawan/region/us915.go | 110 +++++++++++++++++++++++++++++++ 6 files changed, 220 insertions(+), 54 deletions(-) create mode 100644 lora/lorawan/region/us915.go diff --git a/lora/config.go b/lora/config.go index 84e77bb69..dd61dc1d7 100644 --- a/lora/config.go +++ b/lora/config.go @@ -80,6 +80,9 @@ const ( const ( MHz_868_1 = 868100000 MHz_868_5 = 868500000 + MHz_902_3 = 902300000 + Mhz_903_0 = 903000000 + MHZ_915_0 = 915000000 MHz_916_8 = 916800000 MHz_923_3 = 923300000 ) diff --git a/lora/lorawan/adaptor.go b/lora/lorawan/adaptor.go index 803b403fd..573328def 100644 --- a/lora/lorawan/adaptor.go +++ b/lora/lorawan/adaptor.go @@ -52,13 +52,13 @@ func SetPublicNetwork(enabled bool) { } // 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) +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) @@ -84,24 +84,30 @@ func Join(otaa *Otaa, session *Session) error { return err } - // Prepare radio for Join Tx - applyChannelConfig(regionSettings.JoinRequestChannel()) - ActiveRadio.SetIqMode(lora.IQStandard) - ActiveRadio.Tx(payload, LORA_TX_TIMEOUT) - if err != nil { - return err - } - - // Wait for JoinAccept - applyChannelConfig(regionSettings.JoinAcceptChannel()) - ActiveRadio.SetIqMode(lora.IQInverted) - resp, err = ActiveRadio.Rx(LORA_RX_TIMEOUT) - if err != nil { - return err - } - - if resp == nil { - return ErrNoJoinAcceptReceived + for { + joinRequestChannel := regionSettings.JoinRequestChannel() + joinAcceptChannel := regionSettings.JoinAcceptChannel() + + // Prepare radio for Join Tx + applyChannelConfig(joinRequestChannel) + ActiveRadio.SetIqMode(lora.IQStandard) + ActiveRadio.Tx(payload, LORA_TX_TIMEOUT) + if err != nil { + return err + } + + // Wait for JoinAccept + if joinAcceptChannel.Frequency() != 0 { + applyChannelConfig(joinAcceptChannel) + } + ActiveRadio.SetIqMode(lora.IQInverted) + resp, err = ActiveRadio.Rx(LORA_RX_TIMEOUT) + if err == nil && resp != nil { + break + } + if !joinAcceptChannel.Next() { + return ErrNoJoinAcceptReceived + } } err = otaa.DecodeJoinAccept(resp, session) diff --git a/lora/lorawan/region/au915.go b/lora/lorawan/region/au915.go index 7a4a4c158..5a63b2dd3 100644 --- a/lora/lorawan/region/au915.go +++ b/lora/lorawan/region/au915.go @@ -7,27 +7,48 @@ const ( AU915_DEFAULT_TX_POWER_DBM = 20 ) +type ChannelAU struct { + frequency uint32 + bandwidth uint8 + spreadingFactor uint8 + codingRate uint8 + preambleLength uint16 + txPowerDBm int8 +} + +// Getter functions +func (c *ChannelAU) Frequency() uint32 { return c.frequency } +func (c *ChannelAU) Bandwidth() uint8 { return c.bandwidth } +func (c *ChannelAU) SpreadingFactor() uint8 { return c.spreadingFactor } +func (c *ChannelAU) CodingRate() uint8 { return c.codingRate } +func (c *ChannelAU) PreambleLength() uint16 { return c.preambleLength } +func (c *ChannelAU) TxPowerDBm() int8 { return c.txPowerDBm } + +func (c *ChannelAU) Next() bool { + return false +} + type RegionSettingsAU915 struct { - joinRequestChannel *Channel - joinAcceptChannel *Channel - uplinkChannel *Channel + joinRequestChannel *ChannelAU + joinAcceptChannel *ChannelAU + uplinkChannel *ChannelAU } func AU915() *RegionSettingsAU915 { return &RegionSettingsAU915{ - joinRequestChannel: &Channel{lora.MHz_916_8, + joinRequestChannel: &ChannelAU{lora.MHz_916_8, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_5, AU915_DEFAULT_PREAMBLE_LEN, AU915_DEFAULT_TX_POWER_DBM}, - joinAcceptChannel: &Channel{lora.MHz_923_3, + joinAcceptChannel: &ChannelAU{lora.MHz_923_3, lora.Bandwidth_500_0, lora.SpreadingFactor9, lora.CodingRate4_5, AU915_DEFAULT_PREAMBLE_LEN, AU915_DEFAULT_TX_POWER_DBM}, - uplinkChannel: &Channel{lora.MHz_916_8, + uplinkChannel: &ChannelAU{lora.MHz_916_8, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_5, @@ -36,14 +57,18 @@ func AU915() *RegionSettingsAU915 { } } -func (r *RegionSettingsAU915) JoinRequestChannel() *Channel { +func Next(c *ChannelAU) bool { + return false +} + +func (r *RegionSettingsAU915) JoinRequestChannel() Channel { return r.joinRequestChannel } -func (r *RegionSettingsAU915) JoinAcceptChannel() *Channel { +func (r *RegionSettingsAU915) JoinAcceptChannel() Channel { return r.joinAcceptChannel } -func (r *RegionSettingsAU915) UplinkChannel() *Channel { +func (r *RegionSettingsAU915) UplinkChannel() Channel { return r.uplinkChannel } diff --git a/lora/lorawan/region/eu868.go b/lora/lorawan/region/eu868.go index f4790806e..d35d4a966 100644 --- a/lora/lorawan/region/eu868.go +++ b/lora/lorawan/region/eu868.go @@ -7,27 +7,48 @@ const ( EU868_DEFAULT_TX_POWER_DBM = 20 ) +type ChannelEU struct { + frequency uint32 + bandwidth uint8 + spreadingFactor uint8 + codingRate uint8 + preambleLength uint16 + txPowerDBm int8 +} + +// Getter functions +func (c *ChannelEU) Frequency() uint32 { return c.frequency } +func (c *ChannelEU) Bandwidth() uint8 { return c.bandwidth } +func (c *ChannelEU) SpreadingFactor() uint8 { return c.spreadingFactor } +func (c *ChannelEU) CodingRate() uint8 { return c.codingRate } +func (c *ChannelEU) PreambleLength() uint16 { return c.preambleLength } +func (c *ChannelEU) TxPowerDBm() int8 { return c.txPowerDBm } + +func (c *ChannelEU) Next() bool { + return false +} + type RegionSettingsEU868 struct { - joinRequestChannel *Channel - joinAcceptChannel *Channel - uplinkChannel *Channel + joinRequestChannel *ChannelEU + joinAcceptChannel *ChannelEU + uplinkChannel *ChannelEU } func EU868() *RegionSettingsEU868 { return &RegionSettingsEU868{ - joinRequestChannel: &Channel{lora.MHz_868_1, + joinRequestChannel: &ChannelEU{lora.MHz_868_1, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_7, EU868_DEFAULT_PREAMBLE_LEN, EU868_DEFAULT_TX_POWER_DBM}, - joinAcceptChannel: &Channel{lora.MHz_868_1, + joinAcceptChannel: &ChannelEU{lora.MHz_868_1, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_7, EU868_DEFAULT_PREAMBLE_LEN, EU868_DEFAULT_TX_POWER_DBM}, - uplinkChannel: &Channel{lora.MHz_868_1, + uplinkChannel: &ChannelEU{lora.MHz_868_1, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_7, @@ -36,14 +57,14 @@ func EU868() *RegionSettingsEU868 { } } -func (r *RegionSettingsEU868) JoinRequestChannel() *Channel { +func (r *RegionSettingsEU868) JoinRequestChannel() Channel { return r.joinRequestChannel } -func (r *RegionSettingsEU868) JoinAcceptChannel() *Channel { +func (r *RegionSettingsEU868) JoinAcceptChannel() Channel { return r.joinAcceptChannel } -func (r *RegionSettingsEU868) UplinkChannel() *Channel { +func (r *RegionSettingsEU868) UplinkChannel() Channel { return r.uplinkChannel } diff --git a/lora/lorawan/region/regionset.go b/lora/lorawan/region/regionset.go index 981d63ece..7983e6931 100644 --- a/lora/lorawan/region/regionset.go +++ b/lora/lorawan/region/regionset.go @@ -1,16 +1,17 @@ package region -type Channel struct { - Frequency uint32 - Bandwidth uint8 - SpreadingFactor uint8 - CodingRate uint8 - PreambleLength uint16 - TxPowerDBm int8 +type RegionSettings interface { + JoinRequestChannel() Channel + JoinAcceptChannel() Channel + UplinkChannel() Channel } -type RegionSettings interface { - JoinRequestChannel() *Channel - JoinAcceptChannel() *Channel - UplinkChannel() *Channel +type Channel interface { + Next() bool + Frequency() uint32 + Bandwidth() uint8 + SpreadingFactor() uint8 + CodingRate() uint8 + PreambleLength() uint16 + TxPowerDBm() int8 } diff --git a/lora/lorawan/region/us915.go b/lora/lorawan/region/us915.go new file mode 100644 index 000000000..d8046f78d --- /dev/null +++ b/lora/lorawan/region/us915.go @@ -0,0 +1,110 @@ +package region + +import "tinygo.org/x/drivers/lora" + +const ( + US915_DEFAULT_PREAMBLE_LEN = 8 + US915_DEFAULT_TX_POWER_DBM = 20 + US915_FREQUENCY_INCREMENT_DR_0 = 200000 // only for 125 kHz Bandwidth + US915_FREQUENCY_INCREMENT_DR_4 = 1600000 // only for 500 kHz Bandwidth +) + +type ChannelUS struct { + frequency uint32 + bandwidth uint8 + spreadingFactor uint8 + codingRate uint8 + preambleLength uint16 + txPowerDBm int8 +} + +// Getter functions +func (c *ChannelUS) Frequency() uint32 { return c.frequency } +func (c *ChannelUS) Bandwidth() uint8 { return c.bandwidth } +func (c *ChannelUS) SpreadingFactor() uint8 { return c.spreadingFactor } +func (c *ChannelUS) CodingRate() uint8 { return c.codingRate } +func (c *ChannelUS) PreambleLength() uint16 { return c.preambleLength } +func (c *ChannelUS) TxPowerDBm() int8 { return c.txPowerDBm } + +func (c *ChannelUS) Next() bool { + switch c.Bandwidth() { + case lora.Bandwidth_125_0: + freq, ok := stepFrequency125(c.frequency) + if ok { + c.frequency = freq + return true + } else { + c.frequency = lora.Mhz_903_0 + return true + } + case lora.Bandwidth_500_0: + freq, ok := stepFrequency500(c.frequency) + if ok { + c.frequency = freq + return true + } else { + return false + } + } + + return false +} + +func stepFrequency125(freq uint32) (uint32, bool) { + f := freq + US915_FREQUENCY_INCREMENT_DR_0 + if f >= lora.MHZ_915_0 { + return 0, false + } + + return f, true +} + +func stepFrequency500(freq uint32) (uint32, bool) { + f := freq + US915_FREQUENCY_INCREMENT_DR_4 + if f >= lora.MHZ_915_0 { + return 0, false + } + + return f, true +} + +type RegionSettingsUS915 struct { + joinRequestChannel *ChannelUS + joinAcceptChannel *ChannelUS + uplinkChannel *ChannelUS +} + +func US915() *RegionSettingsUS915 { + return &RegionSettingsUS915{ + joinRequestChannel: &ChannelUS{lora.MHz_902_3, + lora.Bandwidth_125_0, + lora.SpreadingFactor10, + lora.CodingRate4_5, + US915_DEFAULT_PREAMBLE_LEN, + US915_DEFAULT_TX_POWER_DBM}, + joinAcceptChannel: &ChannelUS{0, + lora.Bandwidth_500_0, + lora.SpreadingFactor9, + lora.CodingRate4_5, + US915_DEFAULT_PREAMBLE_LEN, + US915_DEFAULT_TX_POWER_DBM}, + uplinkChannel: &ChannelUS{lora.Mhz_903_0, + lora.Bandwidth_500_0, + lora.SpreadingFactor9, + lora.CodingRate4_5, + US915_DEFAULT_PREAMBLE_LEN, + US915_DEFAULT_TX_POWER_DBM}, + } +} + +func (r *RegionSettingsUS915) JoinRequestChannel() Channel { + return r.joinRequestChannel +} + +func (r *RegionSettingsUS915) JoinAcceptChannel() Channel { + return r.joinAcceptChannel +} + +func (r *RegionSettingsUS915) UplinkChannel() Channel { + return r.uplinkChannel +} From 7f099a7ff801b5317edeb6710b6a594d23a42fd6 Mon Sep 17 00:00:00 2001 From: Emilio Garcia Date: Fri, 29 Sep 2023 02:04:41 +0000 Subject: [PATCH 2/6] fix lora us915 logic to step into 500 kHz range --- lora/lorawan/region/us915.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lora/lorawan/region/us915.go b/lora/lorawan/region/us915.go index d8046f78d..b6ab2a6a9 100644 --- a/lora/lorawan/region/us915.go +++ b/lora/lorawan/region/us915.go @@ -32,22 +32,21 @@ func (c *ChannelUS) Next() bool { freq, ok := stepFrequency125(c.frequency) if ok { c.frequency = freq - return true } else { c.frequency = lora.Mhz_903_0 - return true + c.bandwidth = lora.Bandwidth_500_0 } case lora.Bandwidth_500_0: freq, ok := stepFrequency500(c.frequency) if ok { c.frequency = freq - return true } else { + // there are no more frequencies to check after sweeping all 8 500 kHz channels return false } } - return false + return true } func stepFrequency125(freq uint32) (uint32, bool) { From 3508fc48405957634a528e41a94c769a93a6776d Mon Sep 17 00:00:00 2001 From: Emilio Garcia Date: Fri, 13 Oct 2023 13:20:57 -0400 Subject: [PATCH 3/6] LoRa WAN add setter functions --- lora/lorawan/region/au915.go | 8 ++++++++ lora/lorawan/region/eu868.go | 8 ++++++++ lora/lorawan/region/us915.go | 9 +++++++++ 3 files changed, 25 insertions(+) diff --git a/lora/lorawan/region/au915.go b/lora/lorawan/region/au915.go index 5a63b2dd3..cbfd25d07 100644 --- a/lora/lorawan/region/au915.go +++ b/lora/lorawan/region/au915.go @@ -24,6 +24,14 @@ func (c *ChannelAU) CodingRate() uint8 { return c.codingRate } func (c *ChannelAU) PreambleLength() uint16 { return c.preambleLength } func (c *ChannelAU) TxPowerDBm() int8 { return c.txPowerDBm } +// Set functions +func (c *ChannelAU) SetFrequency(v uint32) { c.frequency = v } +func (c *ChannelAU) SetBandwidth(v uint8) { c.bandwidth = v } +func (c *ChannelAU) SetSpreadingFactor(v uint8) { c.spreadingFactor = v } +func (c *ChannelAU) SetCodingRate(v uint8) { c.codingRate = v } +func (c *ChannelAU) SetPreambleLength(v uint16) { c.preambleLength = v } +func (c *ChannelAU) SetTxPowerDBm(v int8) { c.txPowerDBm = v } + func (c *ChannelAU) Next() bool { return false } diff --git a/lora/lorawan/region/eu868.go b/lora/lorawan/region/eu868.go index d35d4a966..d8325ccab 100644 --- a/lora/lorawan/region/eu868.go +++ b/lora/lorawan/region/eu868.go @@ -24,6 +24,14 @@ func (c *ChannelEU) CodingRate() uint8 { return c.codingRate } func (c *ChannelEU) PreambleLength() uint16 { return c.preambleLength } func (c *ChannelEU) TxPowerDBm() int8 { return c.txPowerDBm } +// Set functions +func (c *ChannelEU) SetFrequency(v uint32) { c.frequency = v } +func (c *ChannelEU) SetBandwidth(v uint8) { c.bandwidth = v } +func (c *ChannelEU) SetSpreadingFactor(v uint8) { c.spreadingFactor = v } +func (c *ChannelEU) SetCodingRate(v uint8) { c.codingRate = v } +func (c *ChannelEU) SetPreambleLength(v uint16) { c.preambleLength = v } +func (c *ChannelEU) SetTxPowerDBm(v int8) { c.txPowerDBm = v } + func (c *ChannelEU) Next() bool { return false } diff --git a/lora/lorawan/region/us915.go b/lora/lorawan/region/us915.go index b6ab2a6a9..68ec9771a 100644 --- a/lora/lorawan/region/us915.go +++ b/lora/lorawan/region/us915.go @@ -26,6 +26,15 @@ func (c *ChannelUS) CodingRate() uint8 { return c.codingRate } func (c *ChannelUS) PreambleLength() uint16 { return c.preambleLength } func (c *ChannelUS) TxPowerDBm() int8 { return c.txPowerDBm } +// Set functions +// TODO: validate input +func (c *ChannelUS) SetFrequency(v uint32) { c.frequency = v } +func (c *ChannelUS) SetBandwidth(v uint8) { c.bandwidth = v } +func (c *ChannelUS) SetSpreadingFactor(v uint8) { c.spreadingFactor = v } +func (c *ChannelUS) SetCodingRate(v uint8) { c.codingRate = v } +func (c *ChannelUS) SetPreambleLength(v uint16) { c.preambleLength = v } +func (c *ChannelUS) SetTxPowerDBm(v int8) { c.txPowerDBm = v } + func (c *ChannelUS) Next() bool { switch c.Bandwidth() { case lora.Bandwidth_125_0: From 7b2fa1a92a0238d4649a71fa974aaa6d74b14e0b Mon Sep 17 00:00:00 2001 From: deadprogram Date: Tue, 17 Oct 2023 17:46:49 +0200 Subject: [PATCH 4/6] lora/lorawan: refactor shared functionality for ChannelUS, etc into embedded type named channel, do the same for RegionSettings, and then change RegionSettings to just Settings to avoid the redundant naming. Signed-off-by: deadprogram --- lora/lorawan/adaptor.go | 4 +-- lora/lorawan/region/au915.go | 59 +++++++------------------------ lora/lorawan/region/channel.go | 42 ++++++++++++++++++++++ lora/lorawan/region/eu868.go | 59 +++++++------------------------ lora/lorawan/region/regionset.go | 17 --------- lora/lorawan/region/settings.go | 25 +++++++++++++ lora/lorawan/region/us915.go | 60 +++++++------------------------- 7 files changed, 105 insertions(+), 161 deletions(-) create mode 100644 lora/lorawan/region/channel.go delete mode 100644 lora/lorawan/region/regionset.go create mode 100644 lora/lorawan/region/settings.go diff --git a/lora/lorawan/adaptor.go b/lora/lorawan/adaptor.go index 573328def..382a559c4 100644 --- a/lora/lorawan/adaptor.go +++ b/lora/lorawan/adaptor.go @@ -30,11 +30,11 @@ const ( var ( ActiveRadio lora.Radio Retries = 15 - regionSettings region.RegionSettings + regionSettings region.Settings ) // UseRegionSettings sets current Lorawan Regional parameters -func UseRegionSettings(rs region.RegionSettings) { +func UseRegionSettings(rs region.Settings) { regionSettings = rs } diff --git a/lora/lorawan/region/au915.go b/lora/lorawan/region/au915.go index cbfd25d07..03c41494b 100644 --- a/lora/lorawan/region/au915.go +++ b/lora/lorawan/region/au915.go @@ -8,75 +8,40 @@ const ( ) type ChannelAU struct { - frequency uint32 - bandwidth uint8 - spreadingFactor uint8 - codingRate uint8 - preambleLength uint16 - txPowerDBm int8 + channel } -// Getter functions -func (c *ChannelAU) Frequency() uint32 { return c.frequency } -func (c *ChannelAU) Bandwidth() uint8 { return c.bandwidth } -func (c *ChannelAU) SpreadingFactor() uint8 { return c.spreadingFactor } -func (c *ChannelAU) CodingRate() uint8 { return c.codingRate } -func (c *ChannelAU) PreambleLength() uint16 { return c.preambleLength } -func (c *ChannelAU) TxPowerDBm() int8 { return c.txPowerDBm } - -// Set functions -func (c *ChannelAU) SetFrequency(v uint32) { c.frequency = v } -func (c *ChannelAU) SetBandwidth(v uint8) { c.bandwidth = v } -func (c *ChannelAU) SetSpreadingFactor(v uint8) { c.spreadingFactor = v } -func (c *ChannelAU) SetCodingRate(v uint8) { c.codingRate = v } -func (c *ChannelAU) SetPreambleLength(v uint16) { c.preambleLength = v } -func (c *ChannelAU) SetTxPowerDBm(v int8) { c.txPowerDBm = v } - func (c *ChannelAU) Next() bool { return false } -type RegionSettingsAU915 struct { - joinRequestChannel *ChannelAU - joinAcceptChannel *ChannelAU - uplinkChannel *ChannelAU +type SettingsAU915 struct { + settings } -func AU915() *RegionSettingsAU915 { - return &RegionSettingsAU915{ - joinRequestChannel: &ChannelAU{lora.MHz_916_8, +func AU915() *SettingsAU915 { + return &SettingsAU915{settings: settings{ + joinRequestChannel: &ChannelAU{channel: channel{lora.MHz_916_8, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_5, AU915_DEFAULT_PREAMBLE_LEN, - AU915_DEFAULT_TX_POWER_DBM}, - joinAcceptChannel: &ChannelAU{lora.MHz_923_3, + AU915_DEFAULT_TX_POWER_DBM}}, + joinAcceptChannel: &ChannelAU{channel: channel{lora.MHz_923_3, lora.Bandwidth_500_0, lora.SpreadingFactor9, lora.CodingRate4_5, AU915_DEFAULT_PREAMBLE_LEN, - AU915_DEFAULT_TX_POWER_DBM}, - uplinkChannel: &ChannelAU{lora.MHz_916_8, + AU915_DEFAULT_TX_POWER_DBM}}, + uplinkChannel: &ChannelAU{channel: channel{lora.MHz_916_8, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_5, AU915_DEFAULT_PREAMBLE_LEN, - AU915_DEFAULT_TX_POWER_DBM}, - } + AU915_DEFAULT_TX_POWER_DBM}}, + }} } func Next(c *ChannelAU) bool { return false } - -func (r *RegionSettingsAU915) JoinRequestChannel() Channel { - return r.joinRequestChannel -} - -func (r *RegionSettingsAU915) JoinAcceptChannel() Channel { - return r.joinAcceptChannel -} - -func (r *RegionSettingsAU915) UplinkChannel() Channel { - return r.uplinkChannel -} diff --git a/lora/lorawan/region/channel.go b/lora/lorawan/region/channel.go new file mode 100644 index 000000000..b0e65262a --- /dev/null +++ b/lora/lorawan/region/channel.go @@ -0,0 +1,42 @@ +package region + +type Channel interface { + Next() bool + Frequency() uint32 + Bandwidth() uint8 + SpreadingFactor() uint8 + CodingRate() uint8 + PreambleLength() uint16 + TxPowerDBm() int8 + SetFrequency(v uint32) + SetBandwidth(v uint8) + SetSpreadingFactor(v uint8) + SetCodingRate(v uint8) + SetPreambleLength(v uint16) + SetTxPowerDBm(v int8) +} + +type channel struct { + frequency uint32 + bandwidth uint8 + spreadingFactor uint8 + codingRate uint8 + preambleLength uint16 + txPowerDBm int8 +} + +// Getter functions +func (c *channel) Frequency() uint32 { return c.frequency } +func (c *channel) Bandwidth() uint8 { return c.bandwidth } +func (c *channel) SpreadingFactor() uint8 { return c.spreadingFactor } +func (c *channel) CodingRate() uint8 { return c.codingRate } +func (c *channel) PreambleLength() uint16 { return c.preambleLength } +func (c *channel) TxPowerDBm() int8 { return c.txPowerDBm } + +// Set functions +func (c *channel) SetFrequency(v uint32) { c.frequency = v } +func (c *channel) SetBandwidth(v uint8) { c.bandwidth = v } +func (c *channel) SetSpreadingFactor(v uint8) { c.spreadingFactor = v } +func (c *channel) SetCodingRate(v uint8) { c.codingRate = v } +func (c *channel) SetPreambleLength(v uint16) { c.preambleLength = v } +func (c *channel) SetTxPowerDBm(v int8) { c.txPowerDBm = v } diff --git a/lora/lorawan/region/eu868.go b/lora/lorawan/region/eu868.go index d8325ccab..7eed1f44d 100644 --- a/lora/lorawan/region/eu868.go +++ b/lora/lorawan/region/eu868.go @@ -8,71 +8,36 @@ const ( ) type ChannelEU struct { - frequency uint32 - bandwidth uint8 - spreadingFactor uint8 - codingRate uint8 - preambleLength uint16 - txPowerDBm int8 + channel } -// Getter functions -func (c *ChannelEU) Frequency() uint32 { return c.frequency } -func (c *ChannelEU) Bandwidth() uint8 { return c.bandwidth } -func (c *ChannelEU) SpreadingFactor() uint8 { return c.spreadingFactor } -func (c *ChannelEU) CodingRate() uint8 { return c.codingRate } -func (c *ChannelEU) PreambleLength() uint16 { return c.preambleLength } -func (c *ChannelEU) TxPowerDBm() int8 { return c.txPowerDBm } - -// Set functions -func (c *ChannelEU) SetFrequency(v uint32) { c.frequency = v } -func (c *ChannelEU) SetBandwidth(v uint8) { c.bandwidth = v } -func (c *ChannelEU) SetSpreadingFactor(v uint8) { c.spreadingFactor = v } -func (c *ChannelEU) SetCodingRate(v uint8) { c.codingRate = v } -func (c *ChannelEU) SetPreambleLength(v uint16) { c.preambleLength = v } -func (c *ChannelEU) SetTxPowerDBm(v int8) { c.txPowerDBm = v } - func (c *ChannelEU) Next() bool { return false } -type RegionSettingsEU868 struct { - joinRequestChannel *ChannelEU - joinAcceptChannel *ChannelEU - uplinkChannel *ChannelEU +type SettingsEU868 struct { + settings } -func EU868() *RegionSettingsEU868 { - return &RegionSettingsEU868{ - joinRequestChannel: &ChannelEU{lora.MHz_868_1, +func EU868() *SettingsEU868 { + return &SettingsEU868{settings: settings{ + joinRequestChannel: &ChannelEU{channel: channel{lora.MHz_868_1, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_7, EU868_DEFAULT_PREAMBLE_LEN, - EU868_DEFAULT_TX_POWER_DBM}, - joinAcceptChannel: &ChannelEU{lora.MHz_868_1, + EU868_DEFAULT_TX_POWER_DBM}}, + joinAcceptChannel: &ChannelEU{channel: channel{lora.MHz_868_1, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_7, EU868_DEFAULT_PREAMBLE_LEN, - EU868_DEFAULT_TX_POWER_DBM}, - uplinkChannel: &ChannelEU{lora.MHz_868_1, + EU868_DEFAULT_TX_POWER_DBM}}, + uplinkChannel: &ChannelEU{channel: channel{lora.MHz_868_1, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_7, EU868_DEFAULT_PREAMBLE_LEN, - EU868_DEFAULT_TX_POWER_DBM}, - } -} - -func (r *RegionSettingsEU868) JoinRequestChannel() Channel { - return r.joinRequestChannel -} - -func (r *RegionSettingsEU868) JoinAcceptChannel() Channel { - return r.joinAcceptChannel -} - -func (r *RegionSettingsEU868) UplinkChannel() Channel { - return r.uplinkChannel + EU868_DEFAULT_TX_POWER_DBM}}, + }} } diff --git a/lora/lorawan/region/regionset.go b/lora/lorawan/region/regionset.go deleted file mode 100644 index 7983e6931..000000000 --- a/lora/lorawan/region/regionset.go +++ /dev/null @@ -1,17 +0,0 @@ -package region - -type RegionSettings interface { - JoinRequestChannel() Channel - JoinAcceptChannel() Channel - UplinkChannel() Channel -} - -type Channel interface { - Next() bool - Frequency() uint32 - Bandwidth() uint8 - SpreadingFactor() uint8 - CodingRate() uint8 - PreambleLength() uint16 - TxPowerDBm() int8 -} diff --git a/lora/lorawan/region/settings.go b/lora/lorawan/region/settings.go new file mode 100644 index 000000000..e015c0014 --- /dev/null +++ b/lora/lorawan/region/settings.go @@ -0,0 +1,25 @@ +package region + +type Settings interface { + JoinRequestChannel() Channel + JoinAcceptChannel() Channel + UplinkChannel() Channel +} + +type settings struct { + joinRequestChannel Channel + joinAcceptChannel Channel + uplinkChannel Channel +} + +func (r *settings) JoinRequestChannel() Channel { + return r.joinRequestChannel +} + +func (r *settings) JoinAcceptChannel() Channel { + return r.joinAcceptChannel +} + +func (r *settings) UplinkChannel() Channel { + return r.uplinkChannel +} diff --git a/lora/lorawan/region/us915.go b/lora/lorawan/region/us915.go index 68ec9771a..4149b5b46 100644 --- a/lora/lorawan/region/us915.go +++ b/lora/lorawan/region/us915.go @@ -10,31 +10,9 @@ const ( ) type ChannelUS struct { - frequency uint32 - bandwidth uint8 - spreadingFactor uint8 - codingRate uint8 - preambleLength uint16 - txPowerDBm int8 + channel } -// Getter functions -func (c *ChannelUS) Frequency() uint32 { return c.frequency } -func (c *ChannelUS) Bandwidth() uint8 { return c.bandwidth } -func (c *ChannelUS) SpreadingFactor() uint8 { return c.spreadingFactor } -func (c *ChannelUS) CodingRate() uint8 { return c.codingRate } -func (c *ChannelUS) PreambleLength() uint16 { return c.preambleLength } -func (c *ChannelUS) TxPowerDBm() int8 { return c.txPowerDBm } - -// Set functions -// TODO: validate input -func (c *ChannelUS) SetFrequency(v uint32) { c.frequency = v } -func (c *ChannelUS) SetBandwidth(v uint8) { c.bandwidth = v } -func (c *ChannelUS) SetSpreadingFactor(v uint8) { c.spreadingFactor = v } -func (c *ChannelUS) SetCodingRate(v uint8) { c.codingRate = v } -func (c *ChannelUS) SetPreambleLength(v uint16) { c.preambleLength = v } -func (c *ChannelUS) SetTxPowerDBm(v int8) { c.txPowerDBm = v } - func (c *ChannelUS) Next() bool { switch c.Bandwidth() { case lora.Bandwidth_125_0: @@ -76,43 +54,29 @@ func stepFrequency500(freq uint32) (uint32, bool) { return f, true } -type RegionSettingsUS915 struct { - joinRequestChannel *ChannelUS - joinAcceptChannel *ChannelUS - uplinkChannel *ChannelUS +type SettingsUS915 struct { + settings } -func US915() *RegionSettingsUS915 { - return &RegionSettingsUS915{ - joinRequestChannel: &ChannelUS{lora.MHz_902_3, +func US915() *SettingsUS915 { + return &SettingsUS915{settings: settings{ + joinRequestChannel: &ChannelUS{channel: channel{lora.MHz_902_3, lora.Bandwidth_125_0, lora.SpreadingFactor10, lora.CodingRate4_5, US915_DEFAULT_PREAMBLE_LEN, - US915_DEFAULT_TX_POWER_DBM}, - joinAcceptChannel: &ChannelUS{0, + US915_DEFAULT_TX_POWER_DBM}}, + joinAcceptChannel: &ChannelUS{channel: channel{0, lora.Bandwidth_500_0, lora.SpreadingFactor9, lora.CodingRate4_5, US915_DEFAULT_PREAMBLE_LEN, - US915_DEFAULT_TX_POWER_DBM}, - uplinkChannel: &ChannelUS{lora.Mhz_903_0, + US915_DEFAULT_TX_POWER_DBM}}, + uplinkChannel: &ChannelUS{channel: channel{lora.Mhz_903_0, lora.Bandwidth_500_0, lora.SpreadingFactor9, lora.CodingRate4_5, US915_DEFAULT_PREAMBLE_LEN, - US915_DEFAULT_TX_POWER_DBM}, - } -} - -func (r *RegionSettingsUS915) JoinRequestChannel() Channel { - return r.joinRequestChannel -} - -func (r *RegionSettingsUS915) JoinAcceptChannel() Channel { - return r.joinAcceptChannel -} - -func (r *RegionSettingsUS915) UplinkChannel() Channel { - return r.uplinkChannel + US915_DEFAULT_TX_POWER_DBM}}, + }} } From 871907c4c85b69ca96524edf19862e1b8e28c752 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Tue, 17 Oct 2023 17:49:59 +0200 Subject: [PATCH 5/6] examples/lora/lorawan: add missing functions for simulated interface Signed-off-by: deadprogram --- examples/lora/lorawan/common/sim.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/examples/lora/lorawan/common/sim.go b/examples/lora/lorawan/common/sim.go index 14c919fdc..7f70f5cde 100644 --- a/examples/lora/lorawan/common/sim.go +++ b/examples/lora/lorawan/common/sim.go @@ -23,13 +23,18 @@ func (sr *SimLoraRadio) Rx(timeoutMs uint32) ([]uint8, error) { return nil, nil } -func (sr *SimLoraRadio) SetFrequency(freq uint32) {} -func (sr *SimLoraRadio) SetIqMode(mode uint8) {} -func (sr *SimLoraRadio) SetCodingRate(cr uint8) {} -func (sr *SimLoraRadio) SetBandwidth(bw uint8) {} -func (sr *SimLoraRadio) SetCrc(enable bool) {} -func (sr *SimLoraRadio) SetSpreadingFactor(sf uint8) {} -func (sr *SimLoraRadio) LoraConfig(cnf lora.Config) {} +func (sr *SimLoraRadio) SetFrequency(freq uint32) {} +func (sr *SimLoraRadio) SetIqMode(mode uint8) {} +func (sr *SimLoraRadio) SetCodingRate(cr uint8) {} +func (sr *SimLoraRadio) SetBandwidth(bw uint8) {} +func (sr *SimLoraRadio) SetCrc(enable bool) {} +func (sr *SimLoraRadio) SetSpreadingFactor(sf uint8) {} +func (sr *SimLoraRadio) SetHeaderType(headerType uint8) {} +func (sr *SimLoraRadio) SetPreambleLength(pLen uint16) {} +func (sr *SimLoraRadio) SetPublicNetwork(enabled bool) {} +func (sr *SimLoraRadio) SetSyncWord(syncWord uint16) {} +func (sr *SimLoraRadio) SetTxPower(txPower int8) {} +func (sr *SimLoraRadio) LoraConfig(cnf lora.Config) {} func FirmwareVersion() string { return "simulator " + CurrentVersion() From c8c1676f705208d084f10c95bedda0be433de6e8 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Tue, 17 Oct 2023 17:51:33 +0200 Subject: [PATCH 6/6] examples/lora/lorawan: modify atcmd and basic demo to support choosing any one of the supported regions at compile time by using ldflags. Signed-off-by: deadprogram --- examples/lora/lorawan/atcmd/README.md | 8 ++++---- examples/lora/lorawan/atcmd/main.go | 13 ++++++++++++- examples/lora/lorawan/basic-demo/README.md | 8 ++++---- examples/lora/lorawan/basic-demo/main.go | 17 ++++++++++++++--- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/examples/lora/lorawan/atcmd/README.md b/examples/lora/lorawan/atcmd/README.md index af028c196..31f936e70 100644 --- a/examples/lora/lorawan/atcmd/README.md +++ b/examples/lora/lorawan/atcmd/README.md @@ -23,20 +23,20 @@ Builds/flashes atcmd console application with simulator instead of actual LoRa r tinygo flash -target pico ./examples/lora/lorawan/atcmd/ ``` -## PyBadge with LoRa Featherwing +## PyBadge with LoRa Featherwing for EU868 region Builds/flashes atcmd console application on PyBadge using LoRa Featherwing (RFM95/SX1276). ``` -tinygo flash -target pybadge -tags featherwing ./examples/lora/lorawan/atcmd/ +tinygo flash -target pybadge -tags featherwing -ldflags="-X main.reg=EU868" ./examples/lora/lorawan/atcmd/ ``` -## LoRa-E5 +## LoRa-E5 for US915 region Builds/flashes atcmd console application on Lora-E5 using onboard SX126x. ``` -tinygo flash -target lorae5 ./examples/lora/lorawan/atcmd/ +tinygo flash -target lorae5 -ldflags="-X main.reg=US915" ./examples/lora/lorawan/atcmd/ ``` ## Joining a Public Lorawan Network diff --git a/examples/lora/lorawan/atcmd/main.go b/examples/lora/lorawan/atcmd/main.go index 5b013de52..2b84ff599 100644 --- a/examples/lora/lorawan/atcmd/main.go +++ b/examples/lora/lorawan/atcmd/main.go @@ -32,6 +32,8 @@ var ( defaultTimeout uint32 = 1000 ) +var reg string + func main() { uart.Configure(machine.UARTConfig{TX: tx, RX: rx}) @@ -45,7 +47,16 @@ func main() { otaa = &lorawan.Otaa{} lorawan.UseRadio(radio) - lorawan.UseRegionSettings(region.EU868()) + switch reg { + case "AU915": + lorawan.UseRegionSettings(region.AU915()) + case "EU868": + lorawan.UseRegionSettings(region.EU868()) + case "US915": + lorawan.UseRegionSettings(region.US915()) + default: + lorawan.UseRegionSettings(region.EU868()) + } for { if uart.Buffered() > 0 { diff --git a/examples/lora/lorawan/basic-demo/README.md b/examples/lora/lorawan/basic-demo/README.md index 866f9c8bb..3bf62e455 100644 --- a/examples/lora/lorawan/basic-demo/README.md +++ b/examples/lora/lorawan/basic-demo/README.md @@ -21,16 +21,16 @@ loraConnect: Connected ! tinygo flash -target pico ./examples/lora/lorawan/basic-demo ``` -## PyBadge with LoRa Featherwing +## PyBadge with LoRa Featherwing for EU868 region ``` -tinygo flash -target pybadge -tags featherwing ./examples/lora/lorawan/basic-demo +tinygo flash -target pybadge -tags featherwing -ldflags="-X main.reg=EU868" ./examples/lora/lorawan/basic-demo ``` -## LoRa-E5 +## LoRa-E5 for US915 region ``` -tinygo flash -target lorae5 ./examples/lora/lorawan/basic-demo +tinygo flash -target lorae5 -ldflags="-X main.reg=US915" ./examples/lora/lorawan/basic-demo ``` diff --git a/examples/lora/lorawan/basic-demo/main.go b/examples/lora/lorawan/basic-demo/main.go index b42a16ac2..e845f50b9 100644 --- a/examples/lora/lorawan/basic-demo/main.go +++ b/examples/lora/lorawan/basic-demo/main.go @@ -12,7 +12,10 @@ import ( "tinygo.org/x/drivers/lora/lorawan/region" ) -var debug string +var ( + reg string + debug string +) const ( LORAWAN_JOIN_TIMEOUT_SEC = 180 @@ -67,8 +70,16 @@ func main() { // Connect the lorawan with the Lora Radio device. lorawan.UseRadio(radio) - - lorawan.UseRegionSettings(region.EU868()) + switch reg { + case "AU915": + lorawan.UseRegionSettings(region.AU915()) + case "EU868": + lorawan.UseRegionSettings(region.EU868()) + case "US915": + lorawan.UseRegionSettings(region.US915()) + default: + lorawan.UseRegionSettings(region.EU868()) + } // Configure AppEUI, DevEUI, APPKey, and public/private Lorawan Network setLorawanKeys()