63
63
* LoRaWanBridge 1
64
64
\*********************************************************************************************/
65
65
66
+ /*
67
+ For LoraWan EU bands, the Uplink/Downlink (TX/RX) frequencies can be the same.
68
+ For Others, same Uplink/Downlink (TX/RX) frequencies may not be allowed.
69
+ See: https://lora-alliance.org/wp-content/uploads/2020/11/RP_2-1.0.2.pdf
70
+ */
71
+
72
+ // Determines the channel from the current Uplink LoraSettings
73
+ // return 0..71
74
+ uint32_t LoraWanChannel (void ) {
75
+ float fFrequencyDiff ;
76
+ uint8_t uChannel = 0 ;
77
+
78
+ switch (Lora->settings .region ) {
79
+ case TAS_LORA_REGION_AU915:
80
+ if (125.0 == Lora->settings .bandwidth ) {
81
+ fFrequencyDiff = Lora->settings .frequency - TAS_LORAWAN_AU915_FREQUENCY_UP1;
82
+ uChannel = (0.01 + (fFrequencyDiff / 0.2 )); // 0.01 to fix rounding errors
83
+ } else {
84
+ fFrequencyDiff = Lora->settings .frequency - TAS_LORAWAN_AU915_FREQUENCY_UP2;
85
+ uChannel = 64 + ((0.01 + (fFrequencyDiff / 1.6 )));
86
+ }
87
+ break ;
88
+
89
+ // default:
90
+ // not implemented
91
+ }
92
+ return uChannel;
93
+ }
94
+
95
+ /* ****************************************************************************
96
+ LoraWanRadioInfo()
97
+ Some regional profiles use different radio profiles for the Uplink, RX1, and RX2 transmissions
98
+
99
+ Get radio profiles for the Uplink, and RX1 & RX2 downlink transmissions
100
+ RX1 & RX2 profiles are derived from Lora->settings
101
+
102
+ ****************************************************************************/
103
+ const uint8_t RX1DRs[] PROGMEM = {8 ,9 ,10 ,11 ,12 ,13 ,13 }; // DR0..6
104
+ const uint8_t SF[] PROGMEM = {12 ,11 ,10 ,9 ,8 ,7 ,8 ,0 ,12 ,11 ,10 ,9 ,8 ,7 }; // DR0..13
105
+
106
+ void LoraWanRadioInfo (uint8_t mode, void * pInfo) {
107
+ LoRaWanRadioInfo_t* pResult = (LoRaWanRadioInfo_t*) pInfo;
108
+
109
+ switch (Lora->settings .region ) {
110
+ case TAS_LORA_REGION_AU915: {
111
+ // ////////////// AU915 ////////////////////
112
+ /* ref: https://lora-alliance.org/wp-content/uploads/2020/11/RP_2-1.0.2.pdf page 47
113
+ DR0 LoRa: SF12 / 125 kHz
114
+ DR1 LoRa: SF11 / 125 kHz
115
+ DR2 LoRa: SF10 / 125 kHz <-- JOIN REQUEST
116
+ DR3 LoRa: SF9 / 125 kHz
117
+ DR4 LoRa: SF8 / 125 kHz
118
+ DR5 LoRa: SF7 / 125 kHz
119
+ DR6 LoRa: SF8 / 500 kHz Same as DR12
120
+ DR7 LR-FHSS CR1/3: 1.523 MHz OCW 162
121
+ DR8 LoRa: SF12 / 500 kHz
122
+ DR9 LoRa: SF11 / 500 kHz
123
+ DR10 LoRa: SF10 / 500 kHz
124
+ DR11 LoRa: SF9 / 500 kHz
125
+ DR12 LoRa: SF8 / 500 kHz Same as DR6
126
+ DR13 LoRa: SF7 / 500 kHz
127
+
128
+ UPLINK (RX) CHANNELS
129
+ There are 72 channels
130
+ 0-63: DR0 to 5. Starting 915.2, incrementing by 0.2 Mhz to 927.8 <-- JOIN REQUEST
131
+ 64-71: DR6 . Starting 915.9, incrementing by 1.6 MHz to 927.1
132
+ NOTE: Testing with two Dragino end devices shows they do not play nice with channels 64-71
133
+ 1) LHT52 will JOIN OK on Ch64, but never sends any sensor messages on same channel
134
+ 2) LHT65 will not even broadcast JOIN requests on any of the channels (as required by RP002)
135
+ For this reason, channels above 63 are not permitted.
136
+
137
+ DOWNLINK (TX) CHANNELS
138
+ There are 8 channels
139
+ 0-7: DR8 to 13. Starting 923.3, incrementing by 0.6 MHz to 927.5
140
+
141
+ After an uplink: Downlink (TX) link subchannel = Uplink (RX) Channel Number modulo 8
142
+ e.g. --Uplink (RX)-- --Downlink (TX)--
143
+ Freq Channel Channel Frequency
144
+ 915.2 0 0 923.3
145
+ 927.8 63 7 927.1
146
+
147
+ After an uplink:
148
+ Downlink DR for RX1 must follow this table
149
+ Uplink Downlink
150
+ DR0 DR8
151
+ DR1 DR8
152
+ DR2 DR10 <----- channels 1-62
153
+ DR3 DR11
154
+ DR4 DR12
155
+ DR5 DR13
156
+ DR6 DR13 <------ channels 63-71
157
+
158
+ Downlink DR for RX2 must be DR8
159
+
160
+ Downlink
161
+ Reference: https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf)
162
+ Assume this is in response to an uplink RX, so we already know RX freq & bw & sf
163
+ TX channel depends on RX freq
164
+ DR for RX1 depends on incoming DR (and RX1DROffset)
165
+ DR for RX2 is fixed ar DR8
166
+
167
+ Tasmota does not support different RX1 & RX2 DRs (yet), so just use DR8 and rely on RX2 arriving at end device OK.
168
+ */
169
+ uint32_t uChannel = LoraWanChannel ();
170
+ uint8_t UplinkChannelBand = uChannel %8 ; // 0..7
171
+ switch (mode) {
172
+ case TAS_LORAWAN_RADIO_UPLINK: {
173
+ // if (uChannel > 71) uChannel = 71; See note above
174
+ if (uChannel > 63 ) uChannel = 63 ;
175
+ if (uChannel < 64 ) {
176
+ (*pResult).frequency = TAS_LORAWAN_AU915_FREQUENCY_UP1 + (uChannel * 0.2 );
177
+ (*pResult).bandwidth = TAS_LORAWAN_AU915_BANDWIDTH_UP1; // DR2
178
+ (*pResult).spreading_factor = TAS_LORAWAN_AU915_SPREADING_FACTOR_UP1; // DR2
179
+ } else {
180
+ (*pResult).frequency = TAS_LORAWAN_AU915_FREQUENCY_UP2 + ((uChannel-64 ) * 1.6 );
181
+ (*pResult).bandwidth = TAS_LORAWAN_AU915_BANDWIDTH_UP2; // DR6
182
+ (*pResult).spreading_factor = TAS_LORAWAN_AU915_SPREADING_FACTOR_UP2; // DR6
183
+ }
184
+ break ;
185
+ }
186
+ case TAS_LORAWAN_RADIO_RX1: {
187
+ // RX1 DR depends on the Uplink settings
188
+ // https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
189
+ // Page 41
190
+ uint32_t UplinkDR = (125.0 == Lora->settings .bandwidth ) ? (12 - Lora->settings .spreading_factor ) : 6 ; // 0 .. 6
191
+ uint32_t RX1DR = pgm_read_byte (&RX1DRs[UplinkDR]);
192
+ uint32_t RX1SF = pgm_read_byte (&SF[RX1DR]);
193
+ float RX1BW = (RX1DR > 5 ) ? 500.0 : 125.0 ;
194
+ (*pResult).frequency = TAS_LORAWAN_AU915_FREQUENCY_DN + (UplinkChannelBand * 0.6 );
195
+ (*pResult).bandwidth = RX1BW;
196
+ (*pResult).spreading_factor = RX1SF;
197
+ break ;
198
+ }
199
+ case TAS_LORAWAN_RADIO_RX2: {
200
+ (*pResult).frequency = TAS_LORAWAN_AU915_FREQUENCY_DN;
201
+ (*pResult).bandwidth = TAS_LORAWAN_AU915_BANDWIDTH_RX2;
202
+ (*pResult).spreading_factor = TAS_LORAWAN_AU915_SPREADING_FACTOR_RX2;
203
+ break ;
204
+ }
205
+ // default:
206
+ // not implemented
207
+ }
208
+ break ;
209
+ }
210
+ default : { // TAS_LORA_REGION_EU868
211
+ // Default TX/RX1/TX1 same
212
+ (*pResult).frequency = TAS_LORAWAN_FREQUENCY;
213
+ (*pResult).bandwidth = TAS_LORAWAN_BANDWIDTH;
214
+ (*pResult).spreading_factor = TAS_LORAWAN_SPREADING_FACTOR;
215
+ }
216
+ }
217
+ }
218
+
219
+ bool LoraWanDefaults (uint32_t region = TAS_LORA_REGION_EU868, LoRaWanRadioMode_t mode = TAS_LORAWAN_RADIO_UPLINK) {
220
+ bool multi_profile = false ;
221
+ Lora->settings .region = region;
222
+ switch (region) {
223
+ case TAS_LORA_REGION_AU915:
224
+ // TO DO: Need 3 profiles: Uplink, RX1, RX2
225
+ // Works OK for now as RX2 always received by end device.
226
+ multi_profile = true ;
227
+ if ((Lora->settings .frequency < 915.2 ) || (Lora->settings .frequency > 927.8 )) {
228
+ Lora->settings .frequency = TAS_LORAWAN_AU915_FREQUENCY_UP1;
229
+ }
230
+ LoRaWanRadioInfo_t RadioInfo;
231
+ LoraWanRadioInfo (mode, &RadioInfo); // Region specific
232
+ Lora->settings .frequency = RadioInfo.frequency ;
233
+ Lora->settings .bandwidth = RadioInfo.bandwidth ;
234
+ Lora->settings .spreading_factor = RadioInfo.spreading_factor ;
235
+ break ;
236
+ default : // TAS_LORA_REGION_EU868
237
+ Lora->settings .frequency = TAS_LORAWAN_FREQUENCY;
238
+ Lora->settings .bandwidth = TAS_LORAWAN_BANDWIDTH;
239
+ Lora->settings .spreading_factor = TAS_LORAWAN_SPREADING_FACTOR;
240
+ }
241
+ Lora->settings .coding_rate = TAS_LORAWAN_CODING_RATE;
242
+ Lora->settings .sync_word = TAS_LORAWAN_SYNC_WORD;
243
+ Lora->settings .output_power = TAS_LORAWAN_OUTPUT_POWER;
244
+ Lora->settings .preamble_length = TAS_LORAWAN_PREAMBLE_LENGTH;
245
+ Lora->settings .current_limit = TAS_LORAWAN_CURRENT_LIMIT;
246
+ Lora->settings .implicit_header = TAS_LORAWAN_HEADER;
247
+ Lora->settings .crc_bytes = TAS_LORAWAN_CRC_BYTES;
248
+ return multi_profile;
249
+ }
250
+
66
251
/* ********************************************************************************************\
67
252
* Driver Settings load and save
68
253
\*********************************************************************************************/
@@ -146,6 +331,41 @@ void LoraWanDeleteData(void) {
146
331
#include < Ticker.h>
147
332
Ticker LoraWan_Send;
148
333
334
+ void LoraWanSend (uint8_t * data, uint32_t len, bool uplink_profile) {
335
+ LoraSettings_t RXsettings;
336
+ if (uplink_profile) {
337
+ // Different TX/RX profiles allowed. (e.g. LoRaWAN)
338
+ // For CmndLoraSend() ... do not allow changes.
339
+ RXsettings = Lora->settings ; // Make a copy;
340
+ LoraWanDefaults (Lora->settings .region , TAS_LORAWAN_RADIO_RX2); // Set Downlink profile TO DO: Support different RX1 & RX2 profiles
341
+ Lora->Config ();
342
+ }
343
+ LoraSend (data, len, true );
344
+ if (uplink_profile) {
345
+ Lora->settings = RXsettings; // Restore copy
346
+ Lora->Config ();
347
+ }
348
+ }
349
+
350
+ void LoraWanTickerSend (void ) {
351
+ Lora->send_buffer_step --;
352
+ if (1 == Lora->send_buffer_step ) {
353
+ Lora->rx = true ; // Always send during RX1
354
+ Lora->receive_time = 0 ; // Reset receive timer
355
+ LoraWan_Send.once_ms (TAS_LORAWAN_RECEIVE_DELAY2, LoraWanTickerSend); // Retry after 1000 ms
356
+ }
357
+
358
+ bool uplink_profile = (Lora->settings .region == TAS_LORA_REGION_AU915);
359
+ if (Lora->rx ) { // If received in RX1 do not resend in RX2
360
+ LoraWanSend (Lora->send_buffer , Lora->send_buffer_len , uplink_profile);
361
+ }
362
+
363
+ if (uplink_profile && (0 == Lora->send_buffer_step )) {
364
+ Lora->Init (); // Necessary to re-init the SXxxxx chip in cases where TX/RX frequencies differ
365
+ }
366
+ }
367
+
368
+ /*
149
369
void LoraWanTickerSend(void) {
150
370
Lora->send_buffer_step--;
151
371
if (1 == Lora->send_buffer_step) {
@@ -162,6 +382,7 @@ void LoraWanTickerSend(void) {
162
382
Lora->Init(); // Necessary to re-init the SXxxxx chip in cases where TX/RX frequencies differ
163
383
}
164
384
}
385
+ */
165
386
166
387
void LoraWanSendResponse (uint8_t * buffer, size_t len, uint32_t lorawan_delay) {
167
388
free (Lora->send_buffer ); // Free previous buffer (if any)
@@ -184,7 +405,7 @@ size_t LoraWanCFList(uint8_t * CFList, size_t uLen) {
184
405
case TAS_LORA_REGION_AU915: {
185
406
if (uLen < 16 ) return 0 ;
186
407
187
- uint8_t uChannel = LoraChannel (); // 0..71
408
+ uint8_t uChannel = LoraWanChannel (); // 0..71
188
409
uint8_t uMaskByte = uChannel /8 ; // 0..8
189
410
190
411
// Add first 10 bytes
@@ -279,7 +500,7 @@ void LoraWanSendLinkADRReq(uint32_t node) {
279
500
case TAS_LORA_REGION_AU915: {
280
501
// Ref: https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
281
502
// page 39
282
- uint8_t uChannel = LoraChannel (); // 0..71
503
+ uint8_t uChannel = LoraWanChannel (); // 0..71
283
504
uint8_t ChMaskCntl = uChannel/16.0 ; // 0..4
284
505
uChannel = uChannel%16 ; // 0..15
285
506
uint16_t uMask = 0x01 << uChannel;
0 commit comments