diff --git a/examples/lora/lorawan/atcmd/main.go b/examples/lora/lorawan/atcmd/main.go index 1d8f12e..5b013de 100644 --- a/examples/lora/lorawan/atcmd/main.go +++ b/examples/lora/lorawan/atcmd/main.go @@ -15,6 +15,7 @@ import ( "tinygo.org/x/drivers/examples/lora/lorawan/common" "tinygo.org/x/drivers/lora" "tinygo.org/x/drivers/lora/lorawan" + "tinygo.org/x/drivers/lora/lorawan/region" ) // change these to test a different UART or pins if available @@ -44,6 +45,8 @@ func main() { otaa = &lorawan.Otaa{} lorawan.UseRadio(radio) + lorawan.UseRegionSettings(region.EU868()) + for { if uart.Buffered() > 0 { data, _ := uart.ReadByte() diff --git a/examples/lora/lorawan/basic-demo/main.go b/examples/lora/lorawan/basic-demo/main.go index 1e755ec..571d914 100644 --- a/examples/lora/lorawan/basic-demo/main.go +++ b/examples/lora/lorawan/basic-demo/main.go @@ -9,9 +9,11 @@ import ( "tinygo.org/x/drivers/examples/lora/lorawan/common" "tinygo.org/x/drivers/lora" "tinygo.org/x/drivers/lora/lorawan" + "tinygo.org/x/drivers/lora/lorawan/region" ) const ( + debug = true LORAWAN_JOIN_TIMEOUT_SEC = 180 LORAWAN_RECONNECT_DELAY_SEC = 15 LORAWAN_UPLINK_DELAY_SEC = 60 @@ -81,14 +83,29 @@ func main() { // Connect the lorawan with the Lora Radio device. lorawan.UseRadio(radio) + lorawan.UseRegionSettings(region.EU868()) + // Configure AppEUI, DevEUI, APPKey setLorawanKeys() + if debug { + println("main: Network joined") + println("main: DevEui, " + otaa.GetDevEUI()) + println("main: AppEui, " + otaa.GetAppEUI()) + println("main: DevAddr, " + session.GetDevAddr()) + } + // Try to connect Lorawan network if err := loraConnect(); err != nil { failMessage(err) } + if debug { + println("main: NetID, " + otaa.GetNetID()) + println("main: NwkSKey, " + session.GetNwkSKey()) + println("main: AppSKey, " + session.GetAppSKey()) + println("main: Done") + } // Try to periodicaly send an uplink sample message upCount := 1 for { diff --git a/lora/lorawan/adaptor.go b/lora/lorawan/adaptor.go index f05d5ab..a3db730 100644 --- a/lora/lorawan/adaptor.go +++ b/lora/lorawan/adaptor.go @@ -4,20 +4,22 @@ import ( "errors" "tinygo.org/x/drivers/lora" + "tinygo.org/x/drivers/lora/lorawan/region" ) var ( - ErrNoJoinAcceptReceived = errors.New("no JoinAccept packet received") - ErrNoRadioAttached = errors.New("no LoRa radio attached") - ErrInvalidEuiLength = errors.New("invalid EUI length") - ErrInvalidAppKeyLength = errors.New("invalid AppKey length") - ErrInvalidPacketLength = errors.New("invalid packet length") - ErrInvalidDevAddrLength = errors.New("invalid DevAddr length") - ErrInvalidMic = errors.New("invalid Mic") - ErrFrmPayloadTooLarge = errors.New("FRM payload too large") - ErrInvalidNetIDLength = errors.New("invalid NetID length") - ErrInvalidNwkSKeyLength = errors.New("invalid NwkSKey length") - ErrInvalidAppSKeyLength = errors.New("invalid AppSKey length") + ErrNoJoinAcceptReceived = errors.New("no JoinAccept packet received") + ErrNoRadioAttached = errors.New("no LoRa radio attached") + ErrInvalidEuiLength = errors.New("invalid EUI length") + ErrInvalidAppKeyLength = errors.New("invalid AppKey length") + ErrInvalidPacketLength = errors.New("invalid packet length") + ErrInvalidDevAddrLength = errors.New("invalid DevAddr length") + ErrInvalidMic = errors.New("invalid Mic") + ErrFrmPayloadTooLarge = errors.New("FRM payload too large") + ErrInvalidNetIDLength = errors.New("invalid NetID length") + ErrInvalidNwkSKeyLength = errors.New("invalid NwkSKey length") + ErrInvalidAppSKeyLength = errors.New("invalid AppSKey length") + ErrUndefinedRegionSettings = errors.New("undefined Regionnal Settings ") ) const ( @@ -26,10 +28,15 @@ const ( ) var ( - ActiveRadio lora.Radio - Retries = 15 + ActiveRadio lora.Radio + Retries = 15 + regionSettings region.RegionSettings ) +func UseRegionSettings(rs region.RegionSettings) { + regionSettings = rs +} + func UseRadio(r lora.Radio) { if ActiveRadio != nil { panic("lorawan.ActiveRadio is already set") @@ -44,6 +51,10 @@ func Join(otaa *Otaa, session *Session) error { return ErrNoRadioAttached } + if regionSettings == nil { + return ErrUndefinedRegionSettings + } + otaa.Init() // Send join packet @@ -52,6 +63,12 @@ func Join(otaa *Otaa, session *Session) error { return err } + // Prepare radio for Join Tx + joinChannel := regionSettings.GetJoinRequestChannel() + ActiveRadio.SetFrequency(joinChannel.Frequency) + ActiveRadio.SetBandwidth(joinChannel.Bandwidth) + ActiveRadio.SetCodingRate(joinChannel.CodingRate) + ActiveRadio.SetSpreadingFactor(joinChannel.SpreadingFactor) ActiveRadio.SetCrc(true) ActiveRadio.SetIqMode(0) // IQ Standard ActiveRadio.Tx(payload, LORA_TX_TIMEOUT) @@ -60,6 +77,11 @@ func Join(otaa *Otaa, session *Session) error { } // Wait for JoinAccept + joinChannel = regionSettings.GetJoinAcceptChannel() + ActiveRadio.SetFrequency(joinChannel.Frequency) + ActiveRadio.SetBandwidth(joinChannel.Bandwidth) + ActiveRadio.SetCodingRate(joinChannel.CodingRate) + ActiveRadio.SetSpreadingFactor(joinChannel.SpreadingFactor) ActiveRadio.SetIqMode(1) // IQ Inverted for i := 0; i < Retries; i++ { resp, err = ActiveRadio.Rx(LORA_RX_TIMEOUT) @@ -83,10 +105,21 @@ func Join(otaa *Otaa, session *Session) error { } func SendUplink(data []uint8, session *Session) error { + + if regionSettings == nil { + return ErrUndefinedRegionSettings + } + payload, err := session.GenMessage(0, []byte(data)) if err != nil { return err } + + joinChannel := regionSettings.GetUplinkChannel() + ActiveRadio.SetFrequency(joinChannel.Frequency) + ActiveRadio.SetBandwidth(joinChannel.Bandwidth) + ActiveRadio.SetCodingRate(joinChannel.CodingRate) + ActiveRadio.SetSpreadingFactor(joinChannel.SpreadingFactor) ActiveRadio.SetCrc(true) ActiveRadio.SetIqMode(0) // IQ Standard ActiveRadio.Tx(payload, LORA_TX_TIMEOUT) diff --git a/lora/lorawan/otaa.go b/lora/lorawan/otaa.go index ea3ed72..2f63640 100644 --- a/lora/lorawan/otaa.go +++ b/lora/lorawan/otaa.go @@ -20,7 +20,6 @@ type Otaa struct { // Initialize DevNonce func (o *Otaa) Init() { o.buf = make([]uint8, 0) - o.generateDevNonce() } diff --git a/lora/lorawan/region/au915.go b/lora/lorawan/region/au915.go new file mode 100644 index 0000000..3168f05 --- /dev/null +++ b/lora/lorawan/region/au915.go @@ -0,0 +1,22 @@ +package region + +import "tinygo.org/x/drivers/lora" + +type RegionSettingsAU915 struct { +} + +func AU915() *RegionSettingsAU915 { + return &RegionSettingsAU915{} +} + +func (r *RegionSettingsAU915) GetJoinRequestChannel() Channel { + return Channel{916800000, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_5} +} + +func (r *RegionSettingsAU915) GetJoinAcceptChannel() Channel { + return Channel{923300000, lora.Bandwidth_500_0, lora.SpreadingFactor9, lora.CodingRate4_5} +} + +func (r *RegionSettingsAU915) GetUplinkChannel() Channel { + return Channel{868500000, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_5} +} diff --git a/lora/lorawan/region/eu868.go b/lora/lorawan/region/eu868.go new file mode 100644 index 0000000..ee81497 --- /dev/null +++ b/lora/lorawan/region/eu868.go @@ -0,0 +1,22 @@ +package region + +import "tinygo.org/x/drivers/lora" + +type RegionSettingsEU868 struct { +} + +func EU868() *RegionSettingsEU868 { + return &RegionSettingsEU868{} +} + +func (r *RegionSettingsEU868) GetJoinRequestChannel() Channel { + return Channel{868100000, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_7} +} + +func (r *RegionSettingsEU868) GetJoinAcceptChannel() Channel { + return Channel{868100000, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_7} +} + +func (r *RegionSettingsEU868) GetUplinkChannel() Channel { + return Channel{868100000, lora.Bandwidth_125_0, lora.SpreadingFactor9, lora.CodingRate4_7} +} diff --git a/lora/lorawan/region/regionset.go b/lora/lorawan/region/regionset.go new file mode 100644 index 0000000..cf7dd8d --- /dev/null +++ b/lora/lorawan/region/regionset.go @@ -0,0 +1,14 @@ +package region + +type Channel struct { + Frequency uint32 + Bandwidth uint8 + SpreadingFactor uint8 + CodingRate uint8 +} + +type RegionSettings interface { + GetJoinRequestChannel() Channel + GetJoinAcceptChannel() Channel + GetUplinkChannel() Channel +} diff --git a/sx126x/sx126x.go b/sx126x/sx126x.go index 1ace7f2..0cc4680 100644 --- a/sx126x/sx126x.go +++ b/sx126x/sx126x.go @@ -640,6 +640,7 @@ func (d *Device) Rx(timeoutMs uint32) ([]uint8, error) { irqVal := uint16(SX126X_IRQ_RX_DONE | SX126X_IRQ_TIMEOUT | SX126X_IRQ_CRC_ERR) d.SetStandby() d.SetBufferBaseAddress(0, 0) + d.SetRfFrequency(d.loraConf.Freq) d.SetModulationParams(d.loraConf.Sf, bandwidth(d.loraConf.Bw), d.loraConf.Cr, d.loraConf.Ldr) d.SetPacketParam(d.loraConf.Preamble, d.loraConf.HeaderType, d.loraConf.Crc, 0xFF, d.loraConf.Iq) d.SetDioIrqParams(irqVal, irqVal, SX126X_IRQ_NONE, SX126X_IRQ_NONE)