Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: LoRaWAN-SanJose_Bootcamp LoRaWAN-grove-cayenne LoRaWAN-classC-demo LoRaWAN-grove-cayenne ... more
region_us915.cpp
00001 #include "lorawan_board.h" 00002 #if defined(USE_BAND_915_HYBRID) || defined(USE_BAND_915) 00003 #include <stdint.h> 00004 #include "LoRaMacPrivate.h" 00005 00006 ChannelParams_t Channels[LORA_MAX_NB_CHANNELS]; 00007 uint16_t ChannelsMaskRemaining[6]; 00008 const int8_t TxPowers[] = { 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10 }; 00009 00010 // DR: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 00011 const uint8_t Datarates[] = { 10, 9, 8, 7, 8, 0, 0, 0, 12, 11, 10, 9, 8, 7, 0, 0}; 00012 00013 const uint8_t MaxPayloadOfDatarate[] = { 11, 53, 125, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 }; 00014 00015 bool DisableChannelInMask( uint8_t id, uint16_t* mask ) 00016 { 00017 uint8_t index = 0; 00018 index = id / 16; 00019 00020 if( ( index > 4 ) || ( id >= LORA_MAX_NB_CHANNELS ) ) 00021 { 00022 return false; 00023 } 00024 00025 // Deactivate channel 00026 mask[index] &= ~( 1 << ( id % 16 ) ); 00027 00028 return true; 00029 } 00030 00031 /*! 00032 * Up/Down link data rates offset definition 00033 */ 00034 const int8_t datarateOffsets[5][4] = 00035 { 00036 { DR_10, DR_9 , DR_8 , DR_8 }, // DR_0 00037 { DR_11, DR_10, DR_9 , DR_8 }, // DR_1 00038 { DR_12, DR_11, DR_10, DR_9 }, // DR_2 00039 { DR_13, DR_12, DR_11, DR_10 }, // DR_3 00040 { DR_13, DR_13, DR_12, DR_11 }, // DR_4 00041 }; 00042 00043 uint32_t region_GetRxBandwidth( int8_t datarate ) 00044 { 00045 if( datarate >= DR_4 ) 00046 {// LoRa 500 kHz 00047 return 2; 00048 } 00049 return 0; // LoRa 125 kHz 00050 } 00051 00052 uint16_t region_GetRxSymbolTimeout( int8_t datarate ) 00053 { 00054 switch( datarate ) 00055 { 00056 case DR_0: // SF10 - BW125 00057 return 5; 00058 00059 case DR_1: // SF9 - BW125 00060 case DR_2: // SF8 - BW125 00061 case DR_8: // SF12 - BW500 00062 case DR_9: // SF11 - BW500 00063 case DR_10: // SF10 - BW500 00064 return 8; 00065 00066 case DR_3: // SF7 - BW125 00067 case DR_11: // SF9 - BW500 00068 return 10; 00069 00070 case DR_4: // SF8 - BW500 00071 case DR_12: // SF8 - BW500 00072 return 14; 00073 00074 case DR_13: // SF7 - BW500 00075 return 16; 00076 00077 default: 00078 return 0; // LoRa 125 kHz 00079 } 00080 } 00081 00082 void region_rx1_setup(uint8_t ch) 00083 { 00084 int8_t datarate = datarateOffsets[LoRaMacParams.ChannelsDatarate ][LoRaMacParams.Rx1DrOffset ]; 00085 if( datarate < 0 ) 00086 { 00087 datarate = DR_0; 00088 } 00089 00090 RxWindowSetup( 00091 LORAMAC_FIRST_RX1_CHANNEL + ( ch % 8 ) * LORAMAC_STEPWIDTH_RX1_CHANNEL, 00092 datarate, 00093 region_GetRxBandwidth(datarate), 00094 region_GetRxSymbolTimeout(datarate) 00095 ); 00096 } 00097 00098 bool ValidateChannelMask( uint16_t* channelsMask ) 00099 { 00100 bool chanMaskState = false; 00101 uint16_t block1 = 0; 00102 uint16_t block2 = 0; 00103 uint8_t index = 0; 00104 00105 for( uint8_t i = 0; i < 4; i++ ) 00106 { 00107 block1 = channelsMask[i] & 0x00FF; 00108 block2 = channelsMask[i] & 0xFF00; 00109 00110 if( ( CountBits( block1, 16 ) > 5 ) && ( chanMaskState == false ) ) 00111 { 00112 channelsMask[i] &= block1; 00113 channelsMask[4] = 1 << ( i * 2 ); 00114 chanMaskState = true; 00115 index = i; 00116 } 00117 else if( ( CountBits( block2, 16 ) > 5 ) && ( chanMaskState == false ) ) 00118 { 00119 channelsMask[i] &= block2; 00120 channelsMask[4] = 1 << ( i * 2 + 1 ); 00121 chanMaskState = true; 00122 index = i; 00123 } 00124 } 00125 00126 // Do only change the channel mask, if we have found a valid block. 00127 if( chanMaskState == true ) 00128 { 00129 for( uint8_t i = 0; i < 4; i++ ) 00130 { 00131 if( i != index ) 00132 { 00133 channelsMask[i] = 0; 00134 } 00135 } 00136 } 00137 return chanMaskState; 00138 } 00139 00140 void region_adr_request(adr_t* adr) 00141 { 00142 if( adr->chMaskCntl == 6 ) 00143 { 00144 // Enable all 125 kHz channels 00145 adr->channelsMask[0] = 0xFFFF; 00146 adr->channelsMask[1] = 0xFFFF; 00147 adr->channelsMask[2] = 0xFFFF; 00148 adr->channelsMask[3] = 0xFFFF; 00149 // Apply chMask to channels 64 to 71 00150 adr->channelsMask[4] = adr->chMask; 00151 } 00152 else if( adr->chMaskCntl == 7 ) 00153 { 00154 // Disable all 125 kHz channels 00155 adr->channelsMask[0] = 0x0000; 00156 adr->channelsMask[1] = 0x0000; 00157 adr->channelsMask[2] = 0x0000; 00158 adr->channelsMask[3] = 0x0000; 00159 // Apply chMask to channels 64 to 71 00160 adr->channelsMask[4] = adr->chMask; 00161 } 00162 else if( adr->chMaskCntl == 5 ) 00163 { 00164 // RFU 00165 adr->status &= 0xFE; // Channel mask KO 00166 } 00167 else 00168 { 00169 adr->channelsMask[adr->chMaskCntl] = adr->chMask; 00170 00171 // FCC 15.247 paragraph F mandates to hop on at least 2 125 kHz channels 00172 if( ( adr->datarate < DR_4 ) && ( CountNbEnabled125kHzChannels( adr->channelsMask ) < 2 ) ) 00173 { 00174 adr->status &= 0xFE; // Channel mask KO 00175 } 00176 00177 #if defined( USE_BAND_915_HYBRID ) 00178 if( ValidateChannelMask( adr->channelsMask ) == false ) 00179 { 00180 adr->status &= 0xFE; // Channel mask KO 00181 } 00182 #endif 00183 } 00184 00185 00186 if ((adr->status & 0x07) == 0x07) { 00187 // Reset ChannelsMaskRemaining to the new ChannelsMask 00188 ChannelsMaskRemaining[0] &= adr->channelsMask[0]; 00189 ChannelsMaskRemaining[1] &= adr->channelsMask[1]; 00190 ChannelsMaskRemaining[2] &= adr->channelsMask[2]; 00191 ChannelsMaskRemaining[3] &= adr->channelsMask[3]; 00192 ChannelsMaskRemaining[4] = adr->channelsMask[4]; 00193 ChannelsMaskRemaining[5] = adr->channelsMask[5]; 00194 } 00195 } 00196 00197 uint8_t region_CountNbEnabledChannels() 00198 { 00199 return CountNbEnabled125kHzChannels(LoRaMacParams.ChannelsMask ) + CountBits(LoRaMacParams.ChannelsMask [4], 16); 00200 } 00201 00202 uint8_t CountNbEnabled125kHzChannels( uint16_t *channelsMask ) 00203 { 00204 uint8_t nb125kHzChannels = 0; 00205 00206 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS - 8; i += 16, k++ ) 00207 { 00208 nb125kHzChannels += CountBits( channelsMask[k], 16 ); 00209 } 00210 00211 return nb125kHzChannels; 00212 } 00213 00214 static bool SetNextChannel( ) 00215 { 00216 uint8_t nbEnabledChannels = 0; 00217 uint8_t enabledChannels[LORA_MAX_NB_CHANNELS]; 00218 00219 memset( enabledChannels, 0, LORA_MAX_NB_CHANNELS ); 00220 00221 if( CountNbEnabled125kHzChannels( ChannelsMaskRemaining ) == 0 ) 00222 { // Restore default channels 00223 memcpy( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) LoRaMacParams.ChannelsMask , 8 ); 00224 } 00225 if( ( LoRaMacParams.ChannelsDatarate >= DR_4 ) && ( ( ChannelsMaskRemaining[4] & 0x00FF ) == 0 ) ) 00226 { // Make sure, that the channels are activated 00227 ChannelsMaskRemaining[4] = LoRaMacParams.ChannelsMask [4]; 00228 } 00229 00230 // Search how many channels are enabled 00231 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ ) 00232 { 00233 for( uint8_t j = 0; j < 16; j++ ) 00234 { 00235 if( ( ChannelsMaskRemaining[k] & ( 1 << j ) ) != 0 ) 00236 { 00237 if( Channels[i + j].FreqHz == 0 ) 00238 { // Check if the channel is enabled 00239 continue; 00240 } 00241 if( ( ( Channels[i + j].DrRange.Fields.Min <= LoRaMacParams.ChannelsDatarate ) && 00242 ( LoRaMacParams.ChannelsDatarate <= Channels[i + j].DrRange.Fields.Max ) ) == false ) 00243 { // Check if the current channel selection supports the given datarate 00244 continue; 00245 } 00246 enabledChannels[nbEnabledChannels++] = i + j; 00247 } 00248 } 00249 } 00250 00251 if( nbEnabledChannels > 0 ) 00252 { 00253 Channel = enabledChannels[random_at_most( nbEnabledChannels - 1 )]; 00254 if( Channel < ( LORA_MAX_NB_CHANNELS - 8 ) ) 00255 { 00256 DisableChannelInMask( Channel, ChannelsMaskRemaining ); 00257 } 00258 return true; 00259 } 00260 else 00261 { 00262 // Datarate not supported by any channel 00263 return false; 00264 } 00265 } 00266 00267 void region_ScheduleTx( ) 00268 { 00269 // Select channel 00270 while( SetNextChannel() == false ) 00271 { 00272 // Set the default datarate 00273 LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate ; 00274 } 00275 00276 //MAC_PRINTF("ch%u ", Channel); 00277 SendFrameOnChannel( Channel ); 00278 } 00279 00280 void region_tx_setup(int8_t dbm, uint8_t pktLen) 00281 { 00282 int8_t datarate = Datarates[LoRaMacParams.ChannelsDatarate ]; 00283 00284 Radio::set_tx_dbm(dbm); 00285 00286 //MAC_PRINTF("txsetup sf%d dr%u ", datarate, LoRaMacParams.ChannelsDatarate); 00287 00288 if( LoRaMacParams.ChannelsDatarate >= DR_4 ) 00289 { // High speed LoRa channel BW500 kHz 00290 //TxTimeOnAir_us = Radio.TimeOnAir_us( MODEM_LORA, pktLen ); 00291 Radio::LoRaModemConfig(500, datarate, 1); 00292 Radio::LoRaPacketConfig(8, false, true, false); 00293 } 00294 else 00295 { // Normal LoRa channel 00296 //TxTimeOnAir_us = Radio.TimeOnAir_us( MODEM_LORA, pktLen ); 00297 Radio::LoRaModemConfig(125, datarate, 1); 00298 Radio::LoRaPacketConfig(8, false, true, false); 00299 } 00300 } 00301 00302 #define RECEIVE_DELAY2_us 2000000 00303 #define JOIN_ACCEPT_DELAY1_us 5000000 00304 #define JOIN_ACCEPT_DELAY2_us 6000000 00305 const LoRaMacParams_t LoRaMacParamsDefaults = { 00306 /* int8_t ChannelsTxPower; */ LORAMAC_DEFAULT_TX_POWER, 00307 /* int8_t ChannelsDatarate;*/ LORAMAC_DEFAULT_DATARATE, 00308 /* uint32_t MaxRxWindow_us;*/ MAX_RX_WINDOW_us, 00309 /* uint32_t ReceiveDelay1_us;*/ RECEIVE_DELAY1_us, 00310 /* uint32_t ReceiveDelay2_us;*/ RECEIVE_DELAY2_us, 00311 #ifdef LORAWAN_JOIN_EUI 00312 /* uint32_t JoinAcceptDelay1_us;*/ JOIN_ACCEPT_DELAY1_us, 00313 /* uint32_t JoinAcceptDelay2_us;*/ JOIN_ACCEPT_DELAY2_us, 00314 #endif /* LORAWAN_JOIN_EUI */ 00315 /* uint8_t NbTrans;*/ 1, 00316 /* uint8_t Rx1DrOffset;*/ 0, 00317 /* Rx2ChannelParams_t Rx2Channel;*/ RX_WND_2_CHANNEL, 00318 #if defined( USE_BAND_915 ) 00319 /* uint16_t ChannelsMask[6];*/ { 0xffff, 0xffff, 0xffff, 0xffff, 0x00ff, 0x0000}, 00320 /* uint8_t NbEnabledChannels;*/ 72, 00321 #elif defined( USE_BAND_915_HYBRID ) 00322 #if defined(HYBRID_H) 00323 /* uint16_t ChannelsMask[6];*/ { 0x0000, 0x0000, 0x0000, 0xff00, 0x0080, 0x0000}, 00324 #elif defined(HYBRID_G) 00325 /* uint16_t ChannelsMask[6];*/ { 0x0000, 0x0000, 0x0000, 0x00ff, 0x0040, 0x0000}, 00326 #elif defined(HYBRID_F) 00327 /* uint16_t ChannelsMask[6];*/ { 0x0000, 0x0000, 0xff00, 0x0000, 0x0020, 0x0000}, 00328 #elif defined(HYBRID_E) 00329 /* uint16_t ChannelsMask[6];*/ { 0x0000, 0x0000, 0x00ff, 0x0000, 0x0010, 0x0000}, 00330 #elif defined(HYBRID_D) 00331 /* uint16_t ChannelsMask[6];*/ { 0x0000, 0xff00, 0x0000, 0x0000, 0x0008, 0x0000}, 00332 #elif defined(HYBRID_C) 00333 /* uint16_t ChannelsMask[6];*/ { 0x0000, 0x00ff, 0x0000, 0x0000, 0x0004, 0x0000}, 00334 #elif defined(HYBRID_B) 00335 /* uint16_t ChannelsMask[6];*/ { 0xff00, 0x0000, 0x0000, 0x0000, 0x0002, 0x0000}, 00336 #else 00337 /* uint16_t ChannelsMask[6];*/ { 0x00ff, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000}, 00338 #endif 00339 /* uint8_t NbEnabledChannels;*/ 9, 00340 #endif 00341 /* us_timestamp_t MaxListenTime */ 0 /* no LBT in USA */ 00342 }; 00343 00344 void region_mac_init() 00345 { 00346 // 125 kHz channels 00347 for( uint8_t i = 0; i < LORA_MAX_NB_CHANNELS - 8; i++ ) 00348 { 00349 Channels[i].FreqHz = 902.3e6 + i * 200e3; 00350 Channels[i].DrRange.Value = ( DR_3 << 4 ) | DR_0; 00351 Channels[i].Band = 0; 00352 } 00353 // 500 kHz channels 00354 for( uint8_t i = LORA_MAX_NB_CHANNELS - 8; i < LORA_MAX_NB_CHANNELS; i++ ) 00355 { 00356 Channels[i].FreqHz = 903.0e6 + ( i - ( LORA_MAX_NB_CHANNELS - 8 ) ) * 1.6e6; 00357 Channels[i].DrRange.Value = ( DR_4 << 4 ) | DR_4; 00358 Channels[i].Band = 0; 00359 } 00360 } 00361 00362 int8_t 00363 region_LimitTxPower( int8_t txPower ) 00364 { 00365 int8_t resultTxPower = txPower; 00366 00367 if( ( LoRaMacParams.ChannelsDatarate == DR_4 ) || 00368 ( ( LoRaMacParams.ChannelsDatarate >= DR_8 ) && ( LoRaMacParams.ChannelsDatarate <= DR_13 ) ) ) 00369 {// Limit tx power to max 26dBm 00370 resultTxPower = MAX( txPower, TX_POWER_26_DBM ); 00371 } 00372 else 00373 { 00374 if( CountNbEnabled125kHzChannels( LoRaMacParams.ChannelsMask ) < 50 ) 00375 {// Limit tx power to max 21dBm 00376 resultTxPower = MAX( txPower, TX_POWER_20_DBM ); 00377 } 00378 } 00379 return resultTxPower; 00380 } 00381 00382 #ifdef LORAWAN_JOIN_EUI 00383 int8_t 00384 region_AlternateDatarate( uint16_t nbTrials ) 00385 { 00386 if (region_CountNbEnabledChannels() < LoRaMacParamsDefaults.NbEnabledChannels) { 00387 memcpy(LoRaMacParams.ChannelsMask , LoRaMacParamsDefaults.ChannelsMask , sizeof(LoRaMacParams.ChannelsMask )); 00388 LoRaMacParams.NbEnabledChannels = LoRaMacParamsDefaults.NbEnabledChannels; 00389 } 00390 00391 if( ( nbTrials & 0x01 ) == 0x01 ) 00392 { 00393 return DR_4; 00394 } 00395 else 00396 { 00397 return DR_0; 00398 } 00399 } 00400 #endif /* LORAWAN_JOIN_EUI */ 00401 00402 void region_session_start(LoRaMacEventInfoStatus_t status) { } 00403 00404 #endif /* USE_BAND_915_HYBRID || USE_BAND_915 */
Generated on Mon Jul 18 2022 19:16:49 by
1.7.2