LoRaWAN end device MAC layer for SX1272 and SX1276. Supports LoRaWAN-1.0 and LoRaWAN-1.1

Dependencies:   sx12xx_hal

Dependents:   LoRaWAN-SanJose_Bootcamp LoRaWAN-grove-cayenne LoRaWAN-classC-demo LoRaWAN-grove-cayenne ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers region_arib8ch.cpp Source File

region_arib8ch.cpp

00001 //#include "Commissioning.h"
00002 #include "lorawan_board.h"
00003 #if defined(USE_BAND_ARIB_8CH)
00004 #include <stdint.h>
00005 #include "LoRaMacPrivate.h"
00006 
00007 const uint8_t MaxPayloadOfDatarate[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
00008 const uint8_t Datarates[]  = { 12, 11, 10,  9,  8,  7,  7, 50 };
00009 const int8_t TxPowers[]    = { 20, 14, 11,  8,  5,  2 };
00010 
00011 ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] =
00012 {
00013     LC1,
00014     LC2
00015     /* other channels given by mac command */
00016 };
00017 
00018 uint32_t region_GetRxBandwidth( int8_t datarate )
00019 {
00020     if( datarate == DR_6 )
00021     {// LoRa 250 kHz
00022         return 1;
00023     }
00024     return 0; // LoRa 125 kHz
00025 }
00026 
00027 uint16_t region_GetRxSymbolTimeout( int8_t datarate )
00028 {
00029     if( ( datarate == DR_3 ) || ( datarate == DR_4 ) )
00030     { // DR_4, DR_3
00031         return 8;
00032     }
00033     else if( datarate == DR_5 )
00034     {
00035         return 10;
00036     }
00037     else if( datarate == DR_6 )
00038     {
00039         return 14;
00040     }
00041     return 5; // DR_2, DR_1, DR_0
00042 }
00043 
00044 void region_rx1_setup(uint8_t chan)
00045 {
00046     int8_t datarate = LoRaMacParams.ChannelsDatarate  - LoRaMacParams.Rx1DrOffset ;
00047     if( datarate < 0 )
00048     {
00049         datarate = DR_0;
00050     }
00051 
00052     RxWindowSetup(
00053         Channels[chan].FreqHz,
00054         datarate,
00055         region_GetRxBandwidth(datarate),
00056         region_GetRxSymbolTimeout(datarate)
00057     );
00058 }
00059 
00060 static bool SetNextChannel(LoRaMacStatus_t* status)
00061 {
00062     uint8_t nbEnabledChannels = 0;
00063     uint8_t enabledChannels[LORA_MAX_NB_CHANNELS];
00064 
00065     memset( enabledChannels, 0, LORA_MAX_NB_CHANNELS );
00066 
00067     *status = LORAMAC_STATUS_SERVICE_UNKNOWN;
00068     if( CountBits( LoRaMacParams.ChannelsMask [0], 16 ) == 0 )
00069     {
00070         // Re-enable default channels, if no channel is enabled
00071         LoRaMacParams.ChannelsMask [0] = LoRaMacParams.ChannelsMask [0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
00072     }
00073 
00074     // Search how many channels are enabled
00075     for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ )
00076     {
00077         for( uint8_t j = 0; j < 16; j++ )
00078         {
00079             if( ( LoRaMacParams.ChannelsMask [k] & ( 1 << j ) ) != 0 )
00080             {
00081                 if( Channels[i + j].FreqHz == 0 )
00082                 { // Check if the channel is enabled
00083                     continue;
00084                 }
00085 #ifdef OVER_THE_AIR_ACTIVATION
00086                 if (!flags.IsLoRaMacNetworkJoined)
00087                 {
00088                     if( ( JOIN_CHANNELS & ( 1 << j ) ) == 0 )
00089                     {
00090                         continue;
00091                     }
00092                 }
00093 #endif /* OVER_THE_AIR_ACTIVATION  */
00094                 if( ( ( Channels[i + j].DrRange.Fields.Min <= LoRaMacParams.ChannelsDatarate  ) &&
00095                       ( LoRaMacParams.ChannelsDatarate  <= Channels[i + j].DrRange.Fields.Max ) ) == false )
00096                 { // Check if the current channel selection supports the given datarate
00097                     *status = LORAMAC_STATUS_DATARATE_INVALID;
00098                     continue;
00099                 }
00100                 enabledChannels[nbEnabledChannels++] = i + j;
00101             }
00102         }
00103     }
00104 
00105     if( nbEnabledChannels > 0 )
00106     {
00107         Channel = enabledChannels[random_at_most(nbEnabledChannels - 1)];
00108         *status = LORAMAC_STATUS_OK;
00109         return true;
00110     }
00111     else
00112     {
00113         // Datarate not supported by any channel
00114         return false;
00115     }
00116 }
00117 
00118 
00119 static us_timestamp_t defer_uplink_us;
00120 
00121 void region_ScheduleTx( )
00122 {
00123     LoRaMacStatus_t ret;
00124 
00125     if (defer_uplink_us > 0) {
00126         TxDelayedEvent.attach_us(OnTxDelayedIsr, defer_uplink_us);
00127         defer_uplink_us = 0;
00128         return;
00129     }
00130 
00131     if (LoRaMacDeviceClass == CLASS_C) {
00132         Radio::Standby();
00133     }
00134 
00135     // Select channel
00136     if (!SetNextChannel(&ret))
00137     {
00138         // Set the default datarate
00139         LoRaMacParams.ChannelsDatarate  = LoRaMacParamsDefaults.ChannelsDatarate ;
00140         // re-enable default channels
00141         LoRaMacParams.ChannelsMask [0] = LoRaMacParamsDefaults.ChannelsMask [0];
00142         if (!SetNextChannel(&ret))
00143             return;
00144     }
00145 
00146     // Schedule transmission of frame
00147     // Try to send now
00148     SendFrameOnChannel( Channel );
00149 }
00150 
00151 #define RECEIVE_DELAY2_us                           2000000
00152 #define JOIN_ACCEPT_DELAY1_us                          5000000
00153 #define JOIN_ACCEPT_DELAY2_us                          6000000
00154 const LoRaMacParams_t  LoRaMacParamsDefaults = {
00155     /* int8_t ChannelsTxPower */    LORAMAC_DEFAULT_TX_POWER,
00156     /* int8_t ChannelsDatarate */   LORAMAC_DEFAULT_DATARATE,
00157     /* uint32_t MaxRxWindow_us */   MAX_RX_WINDOW_us,
00158     /* uint32_t ReceiveDelay1_us */ RECEIVE_DELAY1_us,
00159     /* uint32_t ReceiveDelay2_us */ RECEIVE_DELAY2_us,
00160 #ifdef LORAWAN_JOIN_EUI
00161     /* uint32_t JoinAcceptDelay1_us */  JOIN_ACCEPT_DELAY1_us,
00162     /* uint32_t JoinAcceptDelay2_us */  JOIN_ACCEPT_DELAY2_us,
00163 #endif /* LORAWAN_JOIN_EUI  */
00164     /* uint8_t NbTrans */   1,
00165     /* uint8_t Rx1DrOffset */   0,
00166     /* Rx2ChannelParams_t Rx2Channel */ RX_WND_2_CHANNEL,
00167     /* uint16_t ChannelsMask[6] */ { (LC(1)+LC(2)), 0, 0, 0, 0, 0},/* only boot channels enabled */
00168     /* uint8_t NbEnabledChannels */ 2,
00169     /* us_timestamp_t MaxListenTime */ 4000000
00170 };
00171 
00172 void region_mac_init()
00173 {
00174 }
00175 
00176 void region_adr_request(adr_t* adr)
00177 {
00178     uint8_t i;
00179 
00180     if( ( adr->chMaskCntl == 0 ) && ( adr->chMask == 0 ) )
00181     {
00182         adr->status &= 0xFE; // Channel mask KO
00183     }
00184     else if( ( ( adr->chMaskCntl >= 1 ) && ( adr->chMaskCntl <= 5 )) ||
00185              ( adr->chMaskCntl >= 7 ) )
00186     {
00187         // RFU
00188         adr->status &= 0xFE; // Channel mask KO
00189     }
00190     else
00191     {
00192         for( i = 0; i < LORA_MAX_NB_CHANNELS; i++ )
00193         {
00194             if( adr->chMaskCntl == 6 )
00195             {
00196                 if( Channels[i].FreqHz != 0 )
00197                 {
00198                     adr->chMask |= 1 << i;
00199                 }
00200             }
00201             else
00202             {
00203                 if( ( ( adr->chMask & ( 1 << i ) ) != 0 ) &&
00204                     ( Channels[i].FreqHz == 0 ) )
00205                 {// Trying to enable an undefined channel
00206                     adr->status &= 0xFE; // Channel mask KO
00207                 }
00208             }
00209         }
00210         adr->channelsMask[0] = adr->chMask;
00211         MAC_PRINTF("arib set channelsMask:%04x ", adr->channelsMask[0]);
00212     }
00213 }
00214 
00215 void region_tx_setup(int8_t txPower, uint8_t pktLen)
00216 {
00217     int8_t datarate = Datarates[LoRaMacParams.ChannelsDatarate ];
00218 
00219     Radio::set_tx_dbm(txPower);
00220 
00221     if( LoRaMacParams.ChannelsDatarate  == DR_7 )
00222     { // High Speed FSK channel
00223         //TxTimeOnAir_us = Radio.TimeOnAir_us( MODEM_FSK, LoRaMacBufferPktLen );
00224         Radio::GFSKModemConfig(datarate * 1000, 50, 25000);
00225         Radio::GFSKPacketConfig(5, false, true);
00226     }
00227     else if( LoRaMacParams.ChannelsDatarate  == DR_6 )
00228     { // High speed LoRa channel
00229         //TxTimeOnAir_us = Radio.TimeOnAir_us( MODEM_LORA, LoRaMacBufferPktLen );
00230         Radio::LoRaModemConfig(250, datarate, 1);
00231         Radio::LoRaPacketConfig(8, false, true, false);
00232     }
00233     else
00234     { // Normal LoRa channel
00235         Radio::LoRaModemConfig(125, datarate, 1);
00236         Radio::LoRaPacketConfig(8, false, true, false);
00237         //TxTimeOnAir_us = Radio.TimeOnAir_us( MODEM_LORA, LoRaMacBufferPktLen );
00238     }
00239 }
00240 
00241 static bool DisableChannelInMask( uint8_t id, uint16_t* mask )
00242 {
00243     uint8_t index = 0;
00244     index = id / 16;
00245 
00246     if( ( index > 4 ) || ( id >= LORA_MAX_NB_CHANNELS ) )
00247     {
00248         return false;
00249     }
00250 
00251     // Deactivate channel
00252     mask[index] &= ~( 1 << ( id % 16 ) );
00253 
00254     return true;
00255 }
00256 
00257 LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id )
00258 {
00259     /*if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
00260     {
00261         if( ( LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG )
00262         {
00263             return LORAMAC_STATUS_BUSY;
00264         }
00265     }*/
00266 
00267     if( ( id < 3 ) || ( id >= LORA_MAX_NB_CHANNELS ) )
00268     {
00269         return LORAMAC_STATUS_PARAMETER_INVALID;
00270     }
00271     else
00272     {
00273         // Remove the channel from the list of channels
00274         Channels[id] = ( ChannelParams_t ){ 0, { 0 }, 0 };
00275 
00276         // Disable the channel as it doesn't exist anymore
00277         if( DisableChannelInMask( id, LoRaMacParams.ChannelsMask  ) == false )
00278         {
00279             return LORAMAC_STATUS_PARAMETER_INVALID;
00280         }
00281     }
00282     return LORAMAC_STATUS_OK;
00283 }
00284 
00285 static bool ValidateDrRange( DrRange_t drRange, int8_t min, int8_t max )
00286 {
00287     int8_t drMin = drRange.Fields.Min & 0x0F;
00288     int8_t drMax = drRange.Fields.Max & 0x0F;
00289 
00290     if( drMin > drMax )
00291     {
00292         return false;
00293     }
00294     if( ValueInRange( drMin, min, max ) == false )
00295     {
00296         return false;
00297     }
00298     if( ValueInRange( drMax, min, max ) == false )
00299     {
00300         return false;
00301     }
00302     return true;
00303 }
00304 
00305 LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params )
00306 {
00307     bool datarateInvalid = false;
00308     bool frequencyInvalid = false;
00309     uint8_t band = 0;
00310 
00311     //MAC_PRINTF("channelAdd(%u,%u)\r\n", id, params.Frequency);
00312     // The id must not exceed LORA_MAX_NB_CHANNELS
00313     if( id >= LORA_MAX_NB_CHANNELS )
00314     {
00315         return LORAMAC_STATUS_PARAMETER_INVALID;
00316     }
00317 
00318     // Validate the datarate
00319     if( ValidateDrRange( params.DrRange, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) == false )
00320     {
00321         datarateInvalid = true;
00322     }
00323 
00324     // Validate the frequency
00325     if( ( Radio::CheckRfFrequency( params.FreqHz ) == true ) && ( params.FreqHz > 0 ) && ( frequencyInvalid == false ) )
00326     {
00327         frequencyInvalid = false;
00328     }
00329     else
00330     {
00331         frequencyInvalid = true;
00332     }
00333 
00334     if( ( datarateInvalid == true ) && ( frequencyInvalid == true ) )
00335     {
00336         return LORAMAC_STATUS_FREQ_AND_DR_INVALID;
00337     }
00338     if( datarateInvalid == true )
00339     {
00340         return LORAMAC_STATUS_DATARATE_INVALID;
00341     }
00342     if( frequencyInvalid == true )
00343     {
00344         return LORAMAC_STATUS_FREQUENCY_INVALID;
00345     }
00346 
00347     // Every parameter is valid, activate the channel
00348     Channels[id] = params;
00349     Channels[id].Band = band;
00350     LoRaMacParams.ChannelsMask [0] |= ( 1 << id );
00351 
00352     return LORAMAC_STATUS_OK;
00353 }
00354 
00355 void
00356 region_session_start(LoRaMacEventInfoStatus_t status)
00357 {
00358     McpsReq_t mcpsReq;
00359         
00360     if (LoRaMacParams.ChannelsMask [0] == 0x003c) {
00361         return;
00362     }
00363     /* send mac commands until desired channel mask */
00364 
00365     mcpsReq.Type = MCPS_UNCONFIRMED;
00366     mcpsReq.Req.fPort = 1;
00367     mcpsReq.Req.fBuffer = NULL;
00368     mcpsReq.Req.fBufferSize = 0;
00369     mcpsReq.Req.Datarate = DR_3;
00370 
00371     defer_uplink_us = 2000000 + random_at_most(2000000);
00372     LoRaMacMcpsRequest( &mcpsReq );
00373 }
00374 
00375 int8_t region_LimitTxPower( int8_t txPower )
00376 {
00377     return txPower;
00378 }
00379 
00380 uint8_t region_CountNbEnabledChannels()
00381 {
00382     return CountBits(LoRaMacParams.ChannelsMask [4], 16);
00383 }
00384 
00385 #ifdef LORAWAN_JOIN_EUI
00386 int8_t
00387 region_AlternateDatarate( uint16_t nbTrials )
00388 {
00389     if( ( nbTrials % 48 ) == 0 )
00390     {
00391         return DR_0;
00392     }
00393     else if( ( nbTrials % 32 ) == 0 )
00394     {
00395         return DR_1;
00396     }
00397     else if( ( nbTrials % 24 ) == 0 )
00398     {
00399         return DR_2;
00400     }
00401     else if( ( nbTrials % 16 ) == 0 )
00402     {
00403         return DR_3;
00404     }
00405     else if( ( nbTrials % 8 ) == 0 )
00406     {
00407         return DR_4;
00408     }
00409     else
00410     {
00411         return DR_5;
00412     }
00413 }
00414 #endif /* LORAWAN_JOIN_EUI  */
00415 
00416 #endif /* USE_BAND_ARIB_8CH */
00417