Skip to content

Commit e95cfe6

Browse files
mirackaradeadprogram
authored andcommitted
LoRa WAN US915 Support
Adds a driver for us 915 protocol to the lora WAN drivers.
1 parent 4edb58c commit e95cfe6

File tree

6 files changed

+220
-54
lines changed

6 files changed

+220
-54
lines changed

lora/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ const (
8080
const (
8181
MHz_868_1 = 868100000
8282
MHz_868_5 = 868500000
83+
MHz_902_3 = 902300000
84+
Mhz_903_0 = 903000000
85+
MHZ_915_0 = 915000000
8386
MHz_916_8 = 916800000
8487
MHz_923_3 = 923300000
8588
)

lora/lorawan/adaptor.go

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@ func SetPublicNetwork(enabled bool) {
5252
}
5353

5454
// ApplyChannelConfig sets current Lora modulation according to current regional settings
55-
func applyChannelConfig(ch *region.Channel) {
56-
ActiveRadio.SetFrequency(ch.Frequency)
57-
ActiveRadio.SetBandwidth(ch.Bandwidth)
58-
ActiveRadio.SetCodingRate(ch.CodingRate)
59-
ActiveRadio.SetSpreadingFactor(ch.SpreadingFactor)
60-
ActiveRadio.SetPreambleLength(ch.PreambleLength)
61-
ActiveRadio.SetTxPower(ch.TxPowerDBm)
55+
func applyChannelConfig(ch region.Channel) {
56+
ActiveRadio.SetFrequency(ch.Frequency())
57+
ActiveRadio.SetBandwidth(ch.Bandwidth())
58+
ActiveRadio.SetCodingRate(ch.CodingRate())
59+
ActiveRadio.SetSpreadingFactor(ch.SpreadingFactor())
60+
ActiveRadio.SetPreambleLength(ch.PreambleLength())
61+
ActiveRadio.SetTxPower(ch.TxPowerDBm())
6262
// Lorawan defaults to explicit headers
6363
ActiveRadio.SetHeaderType(lora.HeaderExplicit)
6464
ActiveRadio.SetCrc(true)
@@ -84,24 +84,30 @@ func Join(otaa *Otaa, session *Session) error {
8484
return err
8585
}
8686

87-
// Prepare radio for Join Tx
88-
applyChannelConfig(regionSettings.JoinRequestChannel())
89-
ActiveRadio.SetIqMode(lora.IQStandard)
90-
ActiveRadio.Tx(payload, LORA_TX_TIMEOUT)
91-
if err != nil {
92-
return err
93-
}
94-
95-
// Wait for JoinAccept
96-
applyChannelConfig(regionSettings.JoinAcceptChannel())
97-
ActiveRadio.SetIqMode(lora.IQInverted)
98-
resp, err = ActiveRadio.Rx(LORA_RX_TIMEOUT)
99-
if err != nil {
100-
return err
101-
}
102-
103-
if resp == nil {
104-
return ErrNoJoinAcceptReceived
87+
for {
88+
joinRequestChannel := regionSettings.JoinRequestChannel()
89+
joinAcceptChannel := regionSettings.JoinAcceptChannel()
90+
91+
// Prepare radio for Join Tx
92+
applyChannelConfig(joinRequestChannel)
93+
ActiveRadio.SetIqMode(lora.IQStandard)
94+
ActiveRadio.Tx(payload, LORA_TX_TIMEOUT)
95+
if err != nil {
96+
return err
97+
}
98+
99+
// Wait for JoinAccept
100+
if joinAcceptChannel.Frequency() != 0 {
101+
applyChannelConfig(joinAcceptChannel)
102+
}
103+
ActiveRadio.SetIqMode(lora.IQInverted)
104+
resp, err = ActiveRadio.Rx(LORA_RX_TIMEOUT)
105+
if err == nil && resp != nil {
106+
break
107+
}
108+
if !joinAcceptChannel.Next() {
109+
return ErrNoJoinAcceptReceived
110+
}
105111
}
106112

107113
err = otaa.DecodeJoinAccept(resp, session)

lora/lorawan/region/au915.go

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,48 @@ const (
77
AU915_DEFAULT_TX_POWER_DBM = 20
88
)
99

10+
type ChannelAU struct {
11+
frequency uint32
12+
bandwidth uint8
13+
spreadingFactor uint8
14+
codingRate uint8
15+
preambleLength uint16
16+
txPowerDBm int8
17+
}
18+
19+
// Getter functions
20+
func (c *ChannelAU) Frequency() uint32 { return c.frequency }
21+
func (c *ChannelAU) Bandwidth() uint8 { return c.bandwidth }
22+
func (c *ChannelAU) SpreadingFactor() uint8 { return c.spreadingFactor }
23+
func (c *ChannelAU) CodingRate() uint8 { return c.codingRate }
24+
func (c *ChannelAU) PreambleLength() uint16 { return c.preambleLength }
25+
func (c *ChannelAU) TxPowerDBm() int8 { return c.txPowerDBm }
26+
27+
func (c *ChannelAU) Next() bool {
28+
return false
29+
}
30+
1031
type RegionSettingsAU915 struct {
11-
joinRequestChannel *Channel
12-
joinAcceptChannel *Channel
13-
uplinkChannel *Channel
32+
joinRequestChannel *ChannelAU
33+
joinAcceptChannel *ChannelAU
34+
uplinkChannel *ChannelAU
1435
}
1536

1637
func AU915() *RegionSettingsAU915 {
1738
return &RegionSettingsAU915{
18-
joinRequestChannel: &Channel{lora.MHz_916_8,
39+
joinRequestChannel: &ChannelAU{lora.MHz_916_8,
1940
lora.Bandwidth_125_0,
2041
lora.SpreadingFactor9,
2142
lora.CodingRate4_5,
2243
AU915_DEFAULT_PREAMBLE_LEN,
2344
AU915_DEFAULT_TX_POWER_DBM},
24-
joinAcceptChannel: &Channel{lora.MHz_923_3,
45+
joinAcceptChannel: &ChannelAU{lora.MHz_923_3,
2546
lora.Bandwidth_500_0,
2647
lora.SpreadingFactor9,
2748
lora.CodingRate4_5,
2849
AU915_DEFAULT_PREAMBLE_LEN,
2950
AU915_DEFAULT_TX_POWER_DBM},
30-
uplinkChannel: &Channel{lora.MHz_916_8,
51+
uplinkChannel: &ChannelAU{lora.MHz_916_8,
3152
lora.Bandwidth_125_0,
3253
lora.SpreadingFactor9,
3354
lora.CodingRate4_5,
@@ -36,14 +57,18 @@ func AU915() *RegionSettingsAU915 {
3657
}
3758
}
3859

39-
func (r *RegionSettingsAU915) JoinRequestChannel() *Channel {
60+
func Next(c *ChannelAU) bool {
61+
return false
62+
}
63+
64+
func (r *RegionSettingsAU915) JoinRequestChannel() Channel {
4065
return r.joinRequestChannel
4166
}
4267

43-
func (r *RegionSettingsAU915) JoinAcceptChannel() *Channel {
68+
func (r *RegionSettingsAU915) JoinAcceptChannel() Channel {
4469
return r.joinAcceptChannel
4570
}
4671

47-
func (r *RegionSettingsAU915) UplinkChannel() *Channel {
72+
func (r *RegionSettingsAU915) UplinkChannel() Channel {
4873
return r.uplinkChannel
4974
}

lora/lorawan/region/eu868.go

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,48 @@ const (
77
EU868_DEFAULT_TX_POWER_DBM = 20
88
)
99

10+
type ChannelEU struct {
11+
frequency uint32
12+
bandwidth uint8
13+
spreadingFactor uint8
14+
codingRate uint8
15+
preambleLength uint16
16+
txPowerDBm int8
17+
}
18+
19+
// Getter functions
20+
func (c *ChannelEU) Frequency() uint32 { return c.frequency }
21+
func (c *ChannelEU) Bandwidth() uint8 { return c.bandwidth }
22+
func (c *ChannelEU) SpreadingFactor() uint8 { return c.spreadingFactor }
23+
func (c *ChannelEU) CodingRate() uint8 { return c.codingRate }
24+
func (c *ChannelEU) PreambleLength() uint16 { return c.preambleLength }
25+
func (c *ChannelEU) TxPowerDBm() int8 { return c.txPowerDBm }
26+
27+
func (c *ChannelEU) Next() bool {
28+
return false
29+
}
30+
1031
type RegionSettingsEU868 struct {
11-
joinRequestChannel *Channel
12-
joinAcceptChannel *Channel
13-
uplinkChannel *Channel
32+
joinRequestChannel *ChannelEU
33+
joinAcceptChannel *ChannelEU
34+
uplinkChannel *ChannelEU
1435
}
1536

1637
func EU868() *RegionSettingsEU868 {
1738
return &RegionSettingsEU868{
18-
joinRequestChannel: &Channel{lora.MHz_868_1,
39+
joinRequestChannel: &ChannelEU{lora.MHz_868_1,
1940
lora.Bandwidth_125_0,
2041
lora.SpreadingFactor9,
2142
lora.CodingRate4_7,
2243
EU868_DEFAULT_PREAMBLE_LEN,
2344
EU868_DEFAULT_TX_POWER_DBM},
24-
joinAcceptChannel: &Channel{lora.MHz_868_1,
45+
joinAcceptChannel: &ChannelEU{lora.MHz_868_1,
2546
lora.Bandwidth_125_0,
2647
lora.SpreadingFactor9,
2748
lora.CodingRate4_7,
2849
EU868_DEFAULT_PREAMBLE_LEN,
2950
EU868_DEFAULT_TX_POWER_DBM},
30-
uplinkChannel: &Channel{lora.MHz_868_1,
51+
uplinkChannel: &ChannelEU{lora.MHz_868_1,
3152
lora.Bandwidth_125_0,
3253
lora.SpreadingFactor9,
3354
lora.CodingRate4_7,
@@ -36,14 +57,14 @@ func EU868() *RegionSettingsEU868 {
3657
}
3758
}
3859

39-
func (r *RegionSettingsEU868) JoinRequestChannel() *Channel {
60+
func (r *RegionSettingsEU868) JoinRequestChannel() Channel {
4061
return r.joinRequestChannel
4162
}
4263

43-
func (r *RegionSettingsEU868) JoinAcceptChannel() *Channel {
64+
func (r *RegionSettingsEU868) JoinAcceptChannel() Channel {
4465
return r.joinAcceptChannel
4566
}
4667

47-
func (r *RegionSettingsEU868) UplinkChannel() *Channel {
68+
func (r *RegionSettingsEU868) UplinkChannel() Channel {
4869
return r.uplinkChannel
4970
}

lora/lorawan/region/regionset.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
package region
22

3-
type Channel struct {
4-
Frequency uint32
5-
Bandwidth uint8
6-
SpreadingFactor uint8
7-
CodingRate uint8
8-
PreambleLength uint16
9-
TxPowerDBm int8
3+
type RegionSettings interface {
4+
JoinRequestChannel() Channel
5+
JoinAcceptChannel() Channel
6+
UplinkChannel() Channel
107
}
118

12-
type RegionSettings interface {
13-
JoinRequestChannel() *Channel
14-
JoinAcceptChannel() *Channel
15-
UplinkChannel() *Channel
9+
type Channel interface {
10+
Next() bool
11+
Frequency() uint32
12+
Bandwidth() uint8
13+
SpreadingFactor() uint8
14+
CodingRate() uint8
15+
PreambleLength() uint16
16+
TxPowerDBm() int8
1617
}

lora/lorawan/region/us915.go

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package region
2+
3+
import "tinygo.org/x/drivers/lora"
4+
5+
const (
6+
US915_DEFAULT_PREAMBLE_LEN = 8
7+
US915_DEFAULT_TX_POWER_DBM = 20
8+
US915_FREQUENCY_INCREMENT_DR_0 = 200000 // only for 125 kHz Bandwidth
9+
US915_FREQUENCY_INCREMENT_DR_4 = 1600000 // only for 500 kHz Bandwidth
10+
)
11+
12+
type ChannelUS struct {
13+
frequency uint32
14+
bandwidth uint8
15+
spreadingFactor uint8
16+
codingRate uint8
17+
preambleLength uint16
18+
txPowerDBm int8
19+
}
20+
21+
// Getter functions
22+
func (c *ChannelUS) Frequency() uint32 { return c.frequency }
23+
func (c *ChannelUS) Bandwidth() uint8 { return c.bandwidth }
24+
func (c *ChannelUS) SpreadingFactor() uint8 { return c.spreadingFactor }
25+
func (c *ChannelUS) CodingRate() uint8 { return c.codingRate }
26+
func (c *ChannelUS) PreambleLength() uint16 { return c.preambleLength }
27+
func (c *ChannelUS) TxPowerDBm() int8 { return c.txPowerDBm }
28+
29+
func (c *ChannelUS) Next() bool {
30+
switch c.Bandwidth() {
31+
case lora.Bandwidth_125_0:
32+
freq, ok := stepFrequency125(c.frequency)
33+
if ok {
34+
c.frequency = freq
35+
return true
36+
} else {
37+
c.frequency = lora.Mhz_903_0
38+
return true
39+
}
40+
case lora.Bandwidth_500_0:
41+
freq, ok := stepFrequency500(c.frequency)
42+
if ok {
43+
c.frequency = freq
44+
return true
45+
} else {
46+
return false
47+
}
48+
}
49+
50+
return false
51+
}
52+
53+
func stepFrequency125(freq uint32) (uint32, bool) {
54+
f := freq + US915_FREQUENCY_INCREMENT_DR_0
55+
if f >= lora.MHZ_915_0 {
56+
return 0, false
57+
}
58+
59+
return f, true
60+
}
61+
62+
func stepFrequency500(freq uint32) (uint32, bool) {
63+
f := freq + US915_FREQUENCY_INCREMENT_DR_4
64+
if f >= lora.MHZ_915_0 {
65+
return 0, false
66+
}
67+
68+
return f, true
69+
}
70+
71+
type RegionSettingsUS915 struct {
72+
joinRequestChannel *ChannelUS
73+
joinAcceptChannel *ChannelUS
74+
uplinkChannel *ChannelUS
75+
}
76+
77+
func US915() *RegionSettingsUS915 {
78+
return &RegionSettingsUS915{
79+
joinRequestChannel: &ChannelUS{lora.MHz_902_3,
80+
lora.Bandwidth_125_0,
81+
lora.SpreadingFactor10,
82+
lora.CodingRate4_5,
83+
US915_DEFAULT_PREAMBLE_LEN,
84+
US915_DEFAULT_TX_POWER_DBM},
85+
joinAcceptChannel: &ChannelUS{0,
86+
lora.Bandwidth_500_0,
87+
lora.SpreadingFactor9,
88+
lora.CodingRate4_5,
89+
US915_DEFAULT_PREAMBLE_LEN,
90+
US915_DEFAULT_TX_POWER_DBM},
91+
uplinkChannel: &ChannelUS{lora.Mhz_903_0,
92+
lora.Bandwidth_500_0,
93+
lora.SpreadingFactor9,
94+
lora.CodingRate4_5,
95+
US915_DEFAULT_PREAMBLE_LEN,
96+
US915_DEFAULT_TX_POWER_DBM},
97+
}
98+
}
99+
100+
func (r *RegionSettingsUS915) JoinRequestChannel() Channel {
101+
return r.joinRequestChannel
102+
}
103+
104+
func (r *RegionSettingsUS915) JoinAcceptChannel() Channel {
105+
return r.joinAcceptChannel
106+
}
107+
108+
func (r *RegionSettingsUS915) UplinkChannel() Channel {
109+
return r.uplinkChannel
110+
}

0 commit comments

Comments
 (0)