Senet / LoRaWAN-lib

Fork of LoRaWAN-lib by canuck lehead

Committer:
Shaun Nelson
Date:
Wed Aug 09 16:20:21 2017 -0400
Branch:
class_b
Revision:
38:182ba91524e4
Synchronized with  https://github.com/Senetco/LoRaMac-node/commit/6cb21de99eaa65caad9d911318df8875867a6e60

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Shaun Nelson 38:182ba91524e4 1 /*
Shaun Nelson 38:182ba91524e4 2 / _____) _ | |
Shaun Nelson 38:182ba91524e4 3 ( (____ _____ ____ _| |_ _____ ____| |__
Shaun Nelson 38:182ba91524e4 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
Shaun Nelson 38:182ba91524e4 5 _____) ) ____| | | || |_| ____( (___| | | |
Shaun Nelson 38:182ba91524e4 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
Shaun Nelson 38:182ba91524e4 7 (C)2013 Semtech
Shaun Nelson 38:182ba91524e4 8 ___ _____ _ ___ _ _____ ___ ___ ___ ___
Shaun Nelson 38:182ba91524e4 9 / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
Shaun Nelson 38:182ba91524e4 10 \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
Shaun Nelson 38:182ba91524e4 11 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
Shaun Nelson 38:182ba91524e4 12 embedded.connectivity.solutions===============
Shaun Nelson 38:182ba91524e4 13
Shaun Nelson 38:182ba91524e4 14 Description: LoRa MAC region CN779 implementation
Shaun Nelson 38:182ba91524e4 15
Shaun Nelson 38:182ba91524e4 16 License: Revised BSD License, see LICENSE.TXT file include in the project
Shaun Nelson 38:182ba91524e4 17
Shaun Nelson 38:182ba91524e4 18 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
Shaun Nelson 38:182ba91524e4 19 */
Shaun Nelson 38:182ba91524e4 20 #include <stdbool.h>
Shaun Nelson 38:182ba91524e4 21 #include <string.h>
Shaun Nelson 38:182ba91524e4 22 #include <stdint.h>
Shaun Nelson 38:182ba91524e4 23 #include <math.h>
Shaun Nelson 38:182ba91524e4 24
Shaun Nelson 38:182ba91524e4 25 #include "board.h"
Shaun Nelson 38:182ba91524e4 26 #include "LoRaMac.h"
Shaun Nelson 38:182ba91524e4 27
Shaun Nelson 38:182ba91524e4 28 #include "utilities.h"
Shaun Nelson 38:182ba91524e4 29
Shaun Nelson 38:182ba91524e4 30 #include "Region.h"
Shaun Nelson 38:182ba91524e4 31 #include "RegionCommon.h"
Shaun Nelson 38:182ba91524e4 32 #include "RegionCN779.h"
Shaun Nelson 38:182ba91524e4 33
Shaun Nelson 38:182ba91524e4 34 // Definitions
Shaun Nelson 38:182ba91524e4 35 #define CHANNELS_MASK_SIZE 1
Shaun Nelson 38:182ba91524e4 36
Shaun Nelson 38:182ba91524e4 37 // Global attributes
Shaun Nelson 38:182ba91524e4 38 /*!
Shaun Nelson 38:182ba91524e4 39 * LoRaMAC channels
Shaun Nelson 38:182ba91524e4 40 */
Shaun Nelson 38:182ba91524e4 41 static ChannelParams_t Channels[CN779_MAX_NB_CHANNELS];
Shaun Nelson 38:182ba91524e4 42
Shaun Nelson 38:182ba91524e4 43 /*!
Shaun Nelson 38:182ba91524e4 44 * LoRaMac bands
Shaun Nelson 38:182ba91524e4 45 */
Shaun Nelson 38:182ba91524e4 46 static Band_t Bands[CN779_MAX_NB_BANDS] =
Shaun Nelson 38:182ba91524e4 47 {
Shaun Nelson 38:182ba91524e4 48 CN779_BAND0
Shaun Nelson 38:182ba91524e4 49 };
Shaun Nelson 38:182ba91524e4 50
Shaun Nelson 38:182ba91524e4 51 /*!
Shaun Nelson 38:182ba91524e4 52 * LoRaMac channels mask
Shaun Nelson 38:182ba91524e4 53 */
Shaun Nelson 38:182ba91524e4 54 static uint16_t ChannelsMask[CHANNELS_MASK_SIZE];
Shaun Nelson 38:182ba91524e4 55
Shaun Nelson 38:182ba91524e4 56 /*!
Shaun Nelson 38:182ba91524e4 57 * LoRaMac channels default mask
Shaun Nelson 38:182ba91524e4 58 */
Shaun Nelson 38:182ba91524e4 59 static uint16_t ChannelsDefaultMask[CHANNELS_MASK_SIZE];
Shaun Nelson 38:182ba91524e4 60
Shaun Nelson 38:182ba91524e4 61 // Static functions
Shaun Nelson 38:182ba91524e4 62 static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr )
Shaun Nelson 38:182ba91524e4 63 {
Shaun Nelson 38:182ba91524e4 64 uint8_t nextLowerDr = 0;
Shaun Nelson 38:182ba91524e4 65
Shaun Nelson 38:182ba91524e4 66 if( dr == minDr )
Shaun Nelson 38:182ba91524e4 67 {
Shaun Nelson 38:182ba91524e4 68 nextLowerDr = minDr;
Shaun Nelson 38:182ba91524e4 69 }
Shaun Nelson 38:182ba91524e4 70 else
Shaun Nelson 38:182ba91524e4 71 {
Shaun Nelson 38:182ba91524e4 72 nextLowerDr = dr - 1;
Shaun Nelson 38:182ba91524e4 73 }
Shaun Nelson 38:182ba91524e4 74 return nextLowerDr;
Shaun Nelson 38:182ba91524e4 75 }
Shaun Nelson 38:182ba91524e4 76
Shaun Nelson 38:182ba91524e4 77 static uint32_t GetBandwidth( uint32_t drIndex )
Shaun Nelson 38:182ba91524e4 78 {
Shaun Nelson 38:182ba91524e4 79 switch( BandwidthsCN779[drIndex] )
Shaun Nelson 38:182ba91524e4 80 {
Shaun Nelson 38:182ba91524e4 81 default:
Shaun Nelson 38:182ba91524e4 82 case 125000:
Shaun Nelson 38:182ba91524e4 83 return 0;
Shaun Nelson 38:182ba91524e4 84 case 250000:
Shaun Nelson 38:182ba91524e4 85 return 1;
Shaun Nelson 38:182ba91524e4 86 case 500000:
Shaun Nelson 38:182ba91524e4 87 return 2;
Shaun Nelson 38:182ba91524e4 88 }
Shaun Nelson 38:182ba91524e4 89 }
Shaun Nelson 38:182ba91524e4 90
Shaun Nelson 38:182ba91524e4 91 static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask )
Shaun Nelson 38:182ba91524e4 92 {
Shaun Nelson 38:182ba91524e4 93 int8_t txPowerResult = txPower;
Shaun Nelson 38:182ba91524e4 94
Shaun Nelson 38:182ba91524e4 95 // Limit tx power to the band max
Shaun Nelson 38:182ba91524e4 96 txPowerResult = MAX( txPower, maxBandTxPower );
Shaun Nelson 38:182ba91524e4 97
Shaun Nelson 38:182ba91524e4 98 return txPowerResult;
Shaun Nelson 38:182ba91524e4 99 }
Shaun Nelson 38:182ba91524e4 100
Shaun Nelson 38:182ba91524e4 101 static bool VerifyTxFreq( uint32_t freq )
Shaun Nelson 38:182ba91524e4 102 {
Shaun Nelson 38:182ba91524e4 103 // Check radio driver support
Shaun Nelson 38:182ba91524e4 104 if( Radio.CheckRfFrequency( freq ) == false )
Shaun Nelson 38:182ba91524e4 105 {
Shaun Nelson 38:182ba91524e4 106 return false;
Shaun Nelson 38:182ba91524e4 107 }
Shaun Nelson 38:182ba91524e4 108
Shaun Nelson 38:182ba91524e4 109 if( ( freq < 779500000 ) || ( freq > 786500000 ) )
Shaun Nelson 38:182ba91524e4 110 {
Shaun Nelson 38:182ba91524e4 111 return false;
Shaun Nelson 38:182ba91524e4 112 }
Shaun Nelson 38:182ba91524e4 113 return true;
Shaun Nelson 38:182ba91524e4 114 }
Shaun Nelson 38:182ba91524e4 115
Shaun Nelson 38:182ba91524e4 116 static uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx )
Shaun Nelson 38:182ba91524e4 117 {
Shaun Nelson 38:182ba91524e4 118 uint8_t nbEnabledChannels = 0;
Shaun Nelson 38:182ba91524e4 119 uint8_t delayTransmission = 0;
Shaun Nelson 38:182ba91524e4 120
Shaun Nelson 38:182ba91524e4 121 for( uint8_t i = 0, k = 0; i < CN779_MAX_NB_CHANNELS; i += 16, k++ )
Shaun Nelson 38:182ba91524e4 122 {
Shaun Nelson 38:182ba91524e4 123 for( uint8_t j = 0; j < 16; j++ )
Shaun Nelson 38:182ba91524e4 124 {
Shaun Nelson 38:182ba91524e4 125 if( ( channelsMask[k] & ( 1 << j ) ) != 0 )
Shaun Nelson 38:182ba91524e4 126 {
Shaun Nelson 38:182ba91524e4 127 if( channels[i + j].Frequency == 0 )
Shaun Nelson 38:182ba91524e4 128 { // Check if the channel is enabled
Shaun Nelson 38:182ba91524e4 129 continue;
Shaun Nelson 38:182ba91524e4 130 }
Shaun Nelson 38:182ba91524e4 131 if( joined == false )
Shaun Nelson 38:182ba91524e4 132 {
Shaun Nelson 38:182ba91524e4 133 if( ( CN779_JOIN_CHANNELS & ( 1 << j ) ) == 0 )
Shaun Nelson 38:182ba91524e4 134 {
Shaun Nelson 38:182ba91524e4 135 continue;
Shaun Nelson 38:182ba91524e4 136 }
Shaun Nelson 38:182ba91524e4 137 }
Shaun Nelson 38:182ba91524e4 138 if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min,
Shaun Nelson 38:182ba91524e4 139 channels[i + j].DrRange.Fields.Max ) == false )
Shaun Nelson 38:182ba91524e4 140 { // Check if the current channel selection supports the given datarate
Shaun Nelson 38:182ba91524e4 141 continue;
Shaun Nelson 38:182ba91524e4 142 }
Shaun Nelson 38:182ba91524e4 143 if( bands[channels[i + j].Band].TimeOff > 0 )
Shaun Nelson 38:182ba91524e4 144 { // Check if the band is available for transmission
Shaun Nelson 38:182ba91524e4 145 delayTransmission++;
Shaun Nelson 38:182ba91524e4 146 continue;
Shaun Nelson 38:182ba91524e4 147 }
Shaun Nelson 38:182ba91524e4 148 enabledChannels[nbEnabledChannels++] = i + j;
Shaun Nelson 38:182ba91524e4 149 }
Shaun Nelson 38:182ba91524e4 150 }
Shaun Nelson 38:182ba91524e4 151 }
Shaun Nelson 38:182ba91524e4 152
Shaun Nelson 38:182ba91524e4 153 *delayTx = delayTransmission;
Shaun Nelson 38:182ba91524e4 154 return nbEnabledChannels;
Shaun Nelson 38:182ba91524e4 155 }
Shaun Nelson 38:182ba91524e4 156
Shaun Nelson 38:182ba91524e4 157 PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy )
Shaun Nelson 38:182ba91524e4 158 {
Shaun Nelson 38:182ba91524e4 159 PhyParam_t phyParam = { 0 };
Shaun Nelson 38:182ba91524e4 160
Shaun Nelson 38:182ba91524e4 161 switch( getPhy->Attribute )
Shaun Nelson 38:182ba91524e4 162 {
Shaun Nelson 38:182ba91524e4 163 case PHY_MIN_RX_DR:
Shaun Nelson 38:182ba91524e4 164 {
Shaun Nelson 38:182ba91524e4 165 phyParam.Value = CN779_RX_MIN_DATARATE;
Shaun Nelson 38:182ba91524e4 166 break;
Shaun Nelson 38:182ba91524e4 167 }
Shaun Nelson 38:182ba91524e4 168 case PHY_MIN_TX_DR:
Shaun Nelson 38:182ba91524e4 169 {
Shaun Nelson 38:182ba91524e4 170 phyParam.Value = CN779_TX_MIN_DATARATE;
Shaun Nelson 38:182ba91524e4 171 break;
Shaun Nelson 38:182ba91524e4 172 }
Shaun Nelson 38:182ba91524e4 173 case PHY_DEF_TX_DR:
Shaun Nelson 38:182ba91524e4 174 {
Shaun Nelson 38:182ba91524e4 175 phyParam.Value = CN779_DEFAULT_DATARATE;
Shaun Nelson 38:182ba91524e4 176 break;
Shaun Nelson 38:182ba91524e4 177 }
Shaun Nelson 38:182ba91524e4 178 case PHY_NEXT_LOWER_TX_DR:
Shaun Nelson 38:182ba91524e4 179 {
Shaun Nelson 38:182ba91524e4 180 phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, CN779_TX_MIN_DATARATE );
Shaun Nelson 38:182ba91524e4 181 break;
Shaun Nelson 38:182ba91524e4 182 }
Shaun Nelson 38:182ba91524e4 183 case PHY_DEF_TX_POWER:
Shaun Nelson 38:182ba91524e4 184 {
Shaun Nelson 38:182ba91524e4 185 phyParam.Value = CN779_DEFAULT_TX_POWER;
Shaun Nelson 38:182ba91524e4 186 break;
Shaun Nelson 38:182ba91524e4 187 }
Shaun Nelson 38:182ba91524e4 188 case PHY_MAX_PAYLOAD:
Shaun Nelson 38:182ba91524e4 189 {
Shaun Nelson 38:182ba91524e4 190 phyParam.Value = MaxPayloadOfDatarateCN779[getPhy->Datarate];
Shaun Nelson 38:182ba91524e4 191 break;
Shaun Nelson 38:182ba91524e4 192 }
Shaun Nelson 38:182ba91524e4 193 case PHY_MAX_PAYLOAD_REPEATER:
Shaun Nelson 38:182ba91524e4 194 {
Shaun Nelson 38:182ba91524e4 195 phyParam.Value = MaxPayloadOfDatarateRepeaterCN779[getPhy->Datarate];
Shaun Nelson 38:182ba91524e4 196 break;
Shaun Nelson 38:182ba91524e4 197 }
Shaun Nelson 38:182ba91524e4 198 case PHY_DUTY_CYCLE:
Shaun Nelson 38:182ba91524e4 199 {
Shaun Nelson 38:182ba91524e4 200 phyParam.Value = CN779_DUTY_CYCLE_ENABLED;
Shaun Nelson 38:182ba91524e4 201 break;
Shaun Nelson 38:182ba91524e4 202 }
Shaun Nelson 38:182ba91524e4 203 case PHY_MAX_RX_WINDOW:
Shaun Nelson 38:182ba91524e4 204 {
Shaun Nelson 38:182ba91524e4 205 phyParam.Value = CN779_MAX_RX_WINDOW;
Shaun Nelson 38:182ba91524e4 206 break;
Shaun Nelson 38:182ba91524e4 207 }
Shaun Nelson 38:182ba91524e4 208 case PHY_RECEIVE_DELAY1:
Shaun Nelson 38:182ba91524e4 209 {
Shaun Nelson 38:182ba91524e4 210 phyParam.Value = CN779_RECEIVE_DELAY1;
Shaun Nelson 38:182ba91524e4 211 break;
Shaun Nelson 38:182ba91524e4 212 }
Shaun Nelson 38:182ba91524e4 213 case PHY_RECEIVE_DELAY2:
Shaun Nelson 38:182ba91524e4 214 {
Shaun Nelson 38:182ba91524e4 215 phyParam.Value = CN779_RECEIVE_DELAY2;
Shaun Nelson 38:182ba91524e4 216 break;
Shaun Nelson 38:182ba91524e4 217 }
Shaun Nelson 38:182ba91524e4 218 case PHY_JOIN_ACCEPT_DELAY1:
Shaun Nelson 38:182ba91524e4 219 {
Shaun Nelson 38:182ba91524e4 220 phyParam.Value = CN779_JOIN_ACCEPT_DELAY1;
Shaun Nelson 38:182ba91524e4 221 break;
Shaun Nelson 38:182ba91524e4 222 }
Shaun Nelson 38:182ba91524e4 223 case PHY_JOIN_ACCEPT_DELAY2:
Shaun Nelson 38:182ba91524e4 224 {
Shaun Nelson 38:182ba91524e4 225 phyParam.Value = CN779_JOIN_ACCEPT_DELAY2;
Shaun Nelson 38:182ba91524e4 226 break;
Shaun Nelson 38:182ba91524e4 227 }
Shaun Nelson 38:182ba91524e4 228 case PHY_MAX_FCNT_GAP:
Shaun Nelson 38:182ba91524e4 229 {
Shaun Nelson 38:182ba91524e4 230 phyParam.Value = CN779_MAX_FCNT_GAP;
Shaun Nelson 38:182ba91524e4 231 break;
Shaun Nelson 38:182ba91524e4 232 }
Shaun Nelson 38:182ba91524e4 233 case PHY_ACK_TIMEOUT:
Shaun Nelson 38:182ba91524e4 234 {
Shaun Nelson 38:182ba91524e4 235 phyParam.Value = ( CN779_ACKTIMEOUT + randr( -CN779_ACK_TIMEOUT_RND, CN779_ACK_TIMEOUT_RND ) );
Shaun Nelson 38:182ba91524e4 236 break;
Shaun Nelson 38:182ba91524e4 237 }
Shaun Nelson 38:182ba91524e4 238 case PHY_DEF_DR1_OFFSET:
Shaun Nelson 38:182ba91524e4 239 {
Shaun Nelson 38:182ba91524e4 240 phyParam.Value = CN779_DEFAULT_RX1_DR_OFFSET;
Shaun Nelson 38:182ba91524e4 241 break;
Shaun Nelson 38:182ba91524e4 242 }
Shaun Nelson 38:182ba91524e4 243 case PHY_DEF_RX2_FREQUENCY:
Shaun Nelson 38:182ba91524e4 244 {
Shaun Nelson 38:182ba91524e4 245 phyParam.Value = CN779_RX_WND_2_FREQ;
Shaun Nelson 38:182ba91524e4 246 break;
Shaun Nelson 38:182ba91524e4 247 }
Shaun Nelson 38:182ba91524e4 248 case PHY_DEF_RX2_DR:
Shaun Nelson 38:182ba91524e4 249 {
Shaun Nelson 38:182ba91524e4 250 phyParam.Value = CN779_RX_WND_2_DR;
Shaun Nelson 38:182ba91524e4 251 break;
Shaun Nelson 38:182ba91524e4 252 }
Shaun Nelson 38:182ba91524e4 253 case PHY_CHANNELS_MASK:
Shaun Nelson 38:182ba91524e4 254 {
Shaun Nelson 38:182ba91524e4 255 phyParam.ChannelsMask = ChannelsMask;
Shaun Nelson 38:182ba91524e4 256 break;
Shaun Nelson 38:182ba91524e4 257 }
Shaun Nelson 38:182ba91524e4 258 case PHY_CHANNELS_DEFAULT_MASK:
Shaun Nelson 38:182ba91524e4 259 {
Shaun Nelson 38:182ba91524e4 260 phyParam.ChannelsMask = ChannelsDefaultMask;
Shaun Nelson 38:182ba91524e4 261 break;
Shaun Nelson 38:182ba91524e4 262 }
Shaun Nelson 38:182ba91524e4 263 case PHY_MAX_NB_CHANNELS:
Shaun Nelson 38:182ba91524e4 264 {
Shaun Nelson 38:182ba91524e4 265 phyParam.Value = CN779_MAX_NB_CHANNELS;
Shaun Nelson 38:182ba91524e4 266 break;
Shaun Nelson 38:182ba91524e4 267 }
Shaun Nelson 38:182ba91524e4 268 case PHY_CHANNELS:
Shaun Nelson 38:182ba91524e4 269 {
Shaun Nelson 38:182ba91524e4 270 phyParam.Channels = Channels;
Shaun Nelson 38:182ba91524e4 271 break;
Shaun Nelson 38:182ba91524e4 272 }
Shaun Nelson 38:182ba91524e4 273 case PHY_DEF_UPLINK_DWELL_TIME:
Shaun Nelson 38:182ba91524e4 274 case PHY_DEF_DOWNLINK_DWELL_TIME:
Shaun Nelson 38:182ba91524e4 275 {
Shaun Nelson 38:182ba91524e4 276 phyParam.Value = 0;
Shaun Nelson 38:182ba91524e4 277 break;
Shaun Nelson 38:182ba91524e4 278 }
Shaun Nelson 38:182ba91524e4 279 case PHY_DEF_MAX_EIRP:
Shaun Nelson 38:182ba91524e4 280 {
Shaun Nelson 38:182ba91524e4 281 phyParam.fValue = CN779_DEFAULT_MAX_EIRP;
Shaun Nelson 38:182ba91524e4 282 break;
Shaun Nelson 38:182ba91524e4 283 }
Shaun Nelson 38:182ba91524e4 284 case PHY_DEF_ANTENNA_GAIN:
Shaun Nelson 38:182ba91524e4 285 {
Shaun Nelson 38:182ba91524e4 286 phyParam.fValue = CN779_DEFAULT_ANTENNA_GAIN;
Shaun Nelson 38:182ba91524e4 287 break;
Shaun Nelson 38:182ba91524e4 288 }
Shaun Nelson 38:182ba91524e4 289 case PHY_NB_JOIN_TRIALS:
Shaun Nelson 38:182ba91524e4 290 case PHY_DEF_NB_JOIN_TRIALS:
Shaun Nelson 38:182ba91524e4 291 {
Shaun Nelson 38:182ba91524e4 292 phyParam.Value = 48;
Shaun Nelson 38:182ba91524e4 293 break;
Shaun Nelson 38:182ba91524e4 294 }
Shaun Nelson 38:182ba91524e4 295 case PHY_BEACON_INTERVAL:
Shaun Nelson 38:182ba91524e4 296 {
Shaun Nelson 38:182ba91524e4 297 phyParam.Value = CN779_BEACON_INTERVAL;
Shaun Nelson 38:182ba91524e4 298 break;
Shaun Nelson 38:182ba91524e4 299 }
Shaun Nelson 38:182ba91524e4 300 case PHY_BEACON_RESERVED:
Shaun Nelson 38:182ba91524e4 301 {
Shaun Nelson 38:182ba91524e4 302 phyParam.Value = CN779_BEACON_RESERVED;
Shaun Nelson 38:182ba91524e4 303 break;
Shaun Nelson 38:182ba91524e4 304 }
Shaun Nelson 38:182ba91524e4 305 case PHY_BEACON_GUARD:
Shaun Nelson 38:182ba91524e4 306 {
Shaun Nelson 38:182ba91524e4 307 phyParam.Value = CN779_BEACON_GUARD;
Shaun Nelson 38:182ba91524e4 308 break;
Shaun Nelson 38:182ba91524e4 309 }
Shaun Nelson 38:182ba91524e4 310 case PHY_BEACON_WINDOW:
Shaun Nelson 38:182ba91524e4 311 {
Shaun Nelson 38:182ba91524e4 312 phyParam.Value = CN779_BEACON_WINDOW;
Shaun Nelson 38:182ba91524e4 313 break;
Shaun Nelson 38:182ba91524e4 314 }
Shaun Nelson 38:182ba91524e4 315 case PHY_BEACON_WINDOW_SLOTS:
Shaun Nelson 38:182ba91524e4 316 {
Shaun Nelson 38:182ba91524e4 317 phyParam.Value = CN779_BEACON_WINDOW_SLOTS;
Shaun Nelson 38:182ba91524e4 318 break;
Shaun Nelson 38:182ba91524e4 319 }
Shaun Nelson 38:182ba91524e4 320 case PHY_PING_SLOT_WINDOW:
Shaun Nelson 38:182ba91524e4 321 {
Shaun Nelson 38:182ba91524e4 322 phyParam.Value = CN779_PING_SLOT_WINDOW;
Shaun Nelson 38:182ba91524e4 323 break;
Shaun Nelson 38:182ba91524e4 324 }
Shaun Nelson 38:182ba91524e4 325 case PHY_BEACON_SYMBOL_TO_DEFAULT:
Shaun Nelson 38:182ba91524e4 326 {
Shaun Nelson 38:182ba91524e4 327 phyParam.Value = CN779_BEACON_SYMBOL_TO_DEFAULT;
Shaun Nelson 38:182ba91524e4 328 break;
Shaun Nelson 38:182ba91524e4 329 }
Shaun Nelson 38:182ba91524e4 330 case PHY_BEACON_SYMBOL_TO_EXPANSION_MAX:
Shaun Nelson 38:182ba91524e4 331 {
Shaun Nelson 38:182ba91524e4 332 phyParam.Value = CN779_BEACON_SYMBOL_TO_EXPANSION_MAX;
Shaun Nelson 38:182ba91524e4 333 break;
Shaun Nelson 38:182ba91524e4 334 }
Shaun Nelson 38:182ba91524e4 335 case PHY_PING_SLOT_SYMBOL_TO_EXPANSION_MAX:
Shaun Nelson 38:182ba91524e4 336 {
Shaun Nelson 38:182ba91524e4 337 phyParam.Value = CN779_PING_SLOT_SYMBOL_TO_EXPANSION_MAX;
Shaun Nelson 38:182ba91524e4 338 break;
Shaun Nelson 38:182ba91524e4 339 }
Shaun Nelson 38:182ba91524e4 340 case PHY_BEACON_SYMBOL_TO_EXPANSION_FACTOR:
Shaun Nelson 38:182ba91524e4 341 {
Shaun Nelson 38:182ba91524e4 342 phyParam.Value = CN779_BEACON_SYMBOL_TO_EXPANSION_FACTOR;
Shaun Nelson 38:182ba91524e4 343 break;
Shaun Nelson 38:182ba91524e4 344 }
Shaun Nelson 38:182ba91524e4 345 case PHY_PING_SLOT_SYMBOL_TO_EXPANSION_FACTOR:
Shaun Nelson 38:182ba91524e4 346 {
Shaun Nelson 38:182ba91524e4 347 phyParam.Value = CN779_PING_SLOT_SYMBOL_TO_EXPANSION_FACTOR;
Shaun Nelson 38:182ba91524e4 348 break;
Shaun Nelson 38:182ba91524e4 349 }
Shaun Nelson 38:182ba91524e4 350 case PHY_MAX_BEACON_LESS_PERIOD:
Shaun Nelson 38:182ba91524e4 351 {
Shaun Nelson 38:182ba91524e4 352 phyParam.Value = CN779_MAX_BEACON_LESS_PERIOD;
Shaun Nelson 38:182ba91524e4 353 break;
Shaun Nelson 38:182ba91524e4 354 }
Shaun Nelson 38:182ba91524e4 355 case PHY_BEACON_DELAY_BEACON_TIMING_ANS:
Shaun Nelson 38:182ba91524e4 356 {
Shaun Nelson 38:182ba91524e4 357 phyParam.Value = CN779_BEACON_DELAY_BEACON_TIMING_ANS;
Shaun Nelson 38:182ba91524e4 358 break;
Shaun Nelson 38:182ba91524e4 359 }
Shaun Nelson 38:182ba91524e4 360 case PHY_BEACON_CHANNEL_FREQ:
Shaun Nelson 38:182ba91524e4 361 {
Shaun Nelson 38:182ba91524e4 362 phyParam.Value = CN779_BEACON_CHANNEL_FREQ;
Shaun Nelson 38:182ba91524e4 363 break;
Shaun Nelson 38:182ba91524e4 364 }
Shaun Nelson 38:182ba91524e4 365 case PHY_PINGSLOT_CHANNEL_FREQ:
Shaun Nelson 38:182ba91524e4 366 {
Shaun Nelson 38:182ba91524e4 367 phyParam.Value = CN779_BEACON_CHANNEL_FREQ;
Shaun Nelson 38:182ba91524e4 368 break;
Shaun Nelson 38:182ba91524e4 369 }
Shaun Nelson 38:182ba91524e4 370 case PHY_BEACON_SIZE:
Shaun Nelson 38:182ba91524e4 371 {
Shaun Nelson 38:182ba91524e4 372 phyParam.Value = CN779_BEACON_SIZE;
Shaun Nelson 38:182ba91524e4 373 break;
Shaun Nelson 38:182ba91524e4 374 }
Shaun Nelson 38:182ba91524e4 375 case PHY_BEACON_CHANNEL_DR:
Shaun Nelson 38:182ba91524e4 376 {
Shaun Nelson 38:182ba91524e4 377 phyParam.Value = CN779_BEACON_CHANNEL_DR;
Shaun Nelson 38:182ba91524e4 378 break;
Shaun Nelson 38:182ba91524e4 379 }
Shaun Nelson 38:182ba91524e4 380 default:
Shaun Nelson 38:182ba91524e4 381 {
Shaun Nelson 38:182ba91524e4 382 break;
Shaun Nelson 38:182ba91524e4 383 }
Shaun Nelson 38:182ba91524e4 384 }
Shaun Nelson 38:182ba91524e4 385
Shaun Nelson 38:182ba91524e4 386 return phyParam;
Shaun Nelson 38:182ba91524e4 387 }
Shaun Nelson 38:182ba91524e4 388
Shaun Nelson 38:182ba91524e4 389 void RegionCN779SetBandTxDone( SetBandTxDoneParams_t* txDone )
Shaun Nelson 38:182ba91524e4 390 {
Shaun Nelson 38:182ba91524e4 391 RegionCommonSetBandTxDone( txDone->Joined, &Bands[Channels[txDone->Channel].Band], txDone->LastTxDoneTime );
Shaun Nelson 38:182ba91524e4 392 }
Shaun Nelson 38:182ba91524e4 393
Shaun Nelson 38:182ba91524e4 394 void RegionCN779InitDefaults( InitType_t type )
Shaun Nelson 38:182ba91524e4 395 {
Shaun Nelson 38:182ba91524e4 396 switch( type )
Shaun Nelson 38:182ba91524e4 397 {
Shaun Nelson 38:182ba91524e4 398 case INIT_TYPE_INIT:
Shaun Nelson 38:182ba91524e4 399 {
Shaun Nelson 38:182ba91524e4 400 // Channels
Shaun Nelson 38:182ba91524e4 401 Channels[0] = ( ChannelParams_t ) CN779_LC1;
Shaun Nelson 38:182ba91524e4 402 Channels[1] = ( ChannelParams_t ) CN779_LC2;
Shaun Nelson 38:182ba91524e4 403 Channels[2] = ( ChannelParams_t ) CN779_LC3;
Shaun Nelson 38:182ba91524e4 404
Shaun Nelson 38:182ba91524e4 405 // Initialize the channels default mask
Shaun Nelson 38:182ba91524e4 406 ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
Shaun Nelson 38:182ba91524e4 407 // Update the channels mask
Shaun Nelson 38:182ba91524e4 408 RegionCommonChanMaskCopy( ChannelsMask, ChannelsDefaultMask, 1 );
Shaun Nelson 38:182ba91524e4 409 break;
Shaun Nelson 38:182ba91524e4 410 }
Shaun Nelson 38:182ba91524e4 411 case INIT_TYPE_RESTORE:
Shaun Nelson 38:182ba91524e4 412 {
Shaun Nelson 38:182ba91524e4 413 // Restore channels default mask
Shaun Nelson 38:182ba91524e4 414 ChannelsMask[0] |= ChannelsDefaultMask[0];
Shaun Nelson 38:182ba91524e4 415 break;
Shaun Nelson 38:182ba91524e4 416 }
Shaun Nelson 38:182ba91524e4 417 default:
Shaun Nelson 38:182ba91524e4 418 {
Shaun Nelson 38:182ba91524e4 419 break;
Shaun Nelson 38:182ba91524e4 420 }
Shaun Nelson 38:182ba91524e4 421 }
Shaun Nelson 38:182ba91524e4 422 }
Shaun Nelson 38:182ba91524e4 423
Shaun Nelson 38:182ba91524e4 424 bool RegionCN779Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute )
Shaun Nelson 38:182ba91524e4 425 {
Shaun Nelson 38:182ba91524e4 426 switch( phyAttribute )
Shaun Nelson 38:182ba91524e4 427 {
Shaun Nelson 38:182ba91524e4 428 case PHY_TX_DR:
Shaun Nelson 38:182ba91524e4 429 {
Shaun Nelson 38:182ba91524e4 430 return RegionCommonValueInRange( verify->DatarateParams.Datarate, CN779_TX_MIN_DATARATE, CN779_TX_MAX_DATARATE );
Shaun Nelson 38:182ba91524e4 431 }
Shaun Nelson 38:182ba91524e4 432 case PHY_DEF_TX_DR:
Shaun Nelson 38:182ba91524e4 433 {
Shaun Nelson 38:182ba91524e4 434 return RegionCommonValueInRange( verify->DatarateParams.Datarate, DR_0, DR_5 );
Shaun Nelson 38:182ba91524e4 435 }
Shaun Nelson 38:182ba91524e4 436 case PHY_RX_DR:
Shaun Nelson 38:182ba91524e4 437 {
Shaun Nelson 38:182ba91524e4 438 return RegionCommonValueInRange( verify->DatarateParams.Datarate, CN779_RX_MIN_DATARATE, CN779_RX_MAX_DATARATE );
Shaun Nelson 38:182ba91524e4 439 }
Shaun Nelson 38:182ba91524e4 440 case PHY_DEF_TX_POWER:
Shaun Nelson 38:182ba91524e4 441 case PHY_TX_POWER:
Shaun Nelson 38:182ba91524e4 442 {
Shaun Nelson 38:182ba91524e4 443 // Remark: switched min and max!
Shaun Nelson 38:182ba91524e4 444 return RegionCommonValueInRange( verify->TxPower, CN779_MAX_TX_POWER, CN779_MIN_TX_POWER );
Shaun Nelson 38:182ba91524e4 445 }
Shaun Nelson 38:182ba91524e4 446 case PHY_DUTY_CYCLE:
Shaun Nelson 38:182ba91524e4 447 {
Shaun Nelson 38:182ba91524e4 448 return CN779_DUTY_CYCLE_ENABLED;
Shaun Nelson 38:182ba91524e4 449 }
Shaun Nelson 38:182ba91524e4 450 case PHY_NB_JOIN_TRIALS:
Shaun Nelson 38:182ba91524e4 451 {
Shaun Nelson 38:182ba91524e4 452 if( verify->NbJoinTrials < 48 )
Shaun Nelson 38:182ba91524e4 453 {
Shaun Nelson 38:182ba91524e4 454 return false;
Shaun Nelson 38:182ba91524e4 455 }
Shaun Nelson 38:182ba91524e4 456 break;
Shaun Nelson 38:182ba91524e4 457 }
Shaun Nelson 38:182ba91524e4 458 default:
Shaun Nelson 38:182ba91524e4 459 return false;
Shaun Nelson 38:182ba91524e4 460 }
Shaun Nelson 38:182ba91524e4 461 return true;
Shaun Nelson 38:182ba91524e4 462 }
Shaun Nelson 38:182ba91524e4 463
Shaun Nelson 38:182ba91524e4 464 void RegionCN779ApplyCFList( ApplyCFListParams_t* applyCFList )
Shaun Nelson 38:182ba91524e4 465 {
Shaun Nelson 38:182ba91524e4 466 ChannelParams_t newChannel;
Shaun Nelson 38:182ba91524e4 467 ChannelAddParams_t channelAdd;
Shaun Nelson 38:182ba91524e4 468 ChannelRemoveParams_t channelRemove;
Shaun Nelson 38:182ba91524e4 469
Shaun Nelson 38:182ba91524e4 470 // Setup default datarate range
Shaun Nelson 38:182ba91524e4 471 newChannel.DrRange.Value = ( DR_5 << 4 ) | DR_0;
Shaun Nelson 38:182ba91524e4 472
Shaun Nelson 38:182ba91524e4 473 // Size of the optional CF list
Shaun Nelson 38:182ba91524e4 474 if( applyCFList->Size != 16 )
Shaun Nelson 38:182ba91524e4 475 {
Shaun Nelson 38:182ba91524e4 476 return;
Shaun Nelson 38:182ba91524e4 477 }
Shaun Nelson 38:182ba91524e4 478
Shaun Nelson 38:182ba91524e4 479 // Last byte is RFU, don't take it into account
Shaun Nelson 38:182ba91524e4 480 for( uint8_t i = 0, chanIdx = CN779_NUMB_DEFAULT_CHANNELS; chanIdx < CN779_MAX_NB_CHANNELS; i+=3, chanIdx++ )
Shaun Nelson 38:182ba91524e4 481 {
Shaun Nelson 38:182ba91524e4 482 if( chanIdx < ( CN779_NUMB_CHANNELS_CF_LIST + CN779_NUMB_DEFAULT_CHANNELS ) )
Shaun Nelson 38:182ba91524e4 483 {
Shaun Nelson 38:182ba91524e4 484 // Channel frequency
Shaun Nelson 38:182ba91524e4 485 newChannel.Frequency = (uint32_t) applyCFList->Payload[i];
Shaun Nelson 38:182ba91524e4 486 newChannel.Frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 );
Shaun Nelson 38:182ba91524e4 487 newChannel.Frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 );
Shaun Nelson 38:182ba91524e4 488 newChannel.Frequency *= 100;
Shaun Nelson 38:182ba91524e4 489
Shaun Nelson 38:182ba91524e4 490 // Initialize alternative frequency to 0
Shaun Nelson 38:182ba91524e4 491 newChannel.Rx1Frequency = 0;
Shaun Nelson 38:182ba91524e4 492 }
Shaun Nelson 38:182ba91524e4 493 else
Shaun Nelson 38:182ba91524e4 494 {
Shaun Nelson 38:182ba91524e4 495 newChannel.Frequency = 0;
Shaun Nelson 38:182ba91524e4 496 newChannel.DrRange.Value = 0;
Shaun Nelson 38:182ba91524e4 497 newChannel.Rx1Frequency = 0;
Shaun Nelson 38:182ba91524e4 498 }
Shaun Nelson 38:182ba91524e4 499
Shaun Nelson 38:182ba91524e4 500 if( newChannel.Frequency != 0 )
Shaun Nelson 38:182ba91524e4 501 {
Shaun Nelson 38:182ba91524e4 502 channelAdd.NewChannel = &newChannel;
Shaun Nelson 38:182ba91524e4 503 channelAdd.ChannelId = chanIdx;
Shaun Nelson 38:182ba91524e4 504
Shaun Nelson 38:182ba91524e4 505 // Try to add all channels
Shaun Nelson 38:182ba91524e4 506 RegionCN779ChannelAdd( &channelAdd );
Shaun Nelson 38:182ba91524e4 507 }
Shaun Nelson 38:182ba91524e4 508 else
Shaun Nelson 38:182ba91524e4 509 {
Shaun Nelson 38:182ba91524e4 510 channelRemove.ChannelId = chanIdx;
Shaun Nelson 38:182ba91524e4 511
Shaun Nelson 38:182ba91524e4 512 RegionCN779ChannelsRemove( &channelRemove );
Shaun Nelson 38:182ba91524e4 513 }
Shaun Nelson 38:182ba91524e4 514 }
Shaun Nelson 38:182ba91524e4 515 }
Shaun Nelson 38:182ba91524e4 516
Shaun Nelson 38:182ba91524e4 517 bool RegionCN779ChanMaskSet( ChanMaskSetParams_t* chanMaskSet )
Shaun Nelson 38:182ba91524e4 518 {
Shaun Nelson 38:182ba91524e4 519 switch( chanMaskSet->ChannelsMaskType )
Shaun Nelson 38:182ba91524e4 520 {
Shaun Nelson 38:182ba91524e4 521 case CHANNELS_MASK:
Shaun Nelson 38:182ba91524e4 522 {
Shaun Nelson 38:182ba91524e4 523 RegionCommonChanMaskCopy( ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 );
Shaun Nelson 38:182ba91524e4 524 break;
Shaun Nelson 38:182ba91524e4 525 }
Shaun Nelson 38:182ba91524e4 526 case CHANNELS_DEFAULT_MASK:
Shaun Nelson 38:182ba91524e4 527 {
Shaun Nelson 38:182ba91524e4 528 RegionCommonChanMaskCopy( ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 );
Shaun Nelson 38:182ba91524e4 529 break;
Shaun Nelson 38:182ba91524e4 530 }
Shaun Nelson 38:182ba91524e4 531 default:
Shaun Nelson 38:182ba91524e4 532 return false;
Shaun Nelson 38:182ba91524e4 533 }
Shaun Nelson 38:182ba91524e4 534 return true;
Shaun Nelson 38:182ba91524e4 535 }
Shaun Nelson 38:182ba91524e4 536
Shaun Nelson 38:182ba91524e4 537 bool RegionCN779AdrNext( AdrNextParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter )
Shaun Nelson 38:182ba91524e4 538 {
Shaun Nelson 38:182ba91524e4 539 bool adrAckReq = false;
Shaun Nelson 38:182ba91524e4 540 int8_t datarate = adrNext->Datarate;
Shaun Nelson 38:182ba91524e4 541 int8_t txPower = adrNext->TxPower;
Shaun Nelson 38:182ba91524e4 542 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 543 PhyParam_t phyParam;
Shaun Nelson 38:182ba91524e4 544
Shaun Nelson 38:182ba91524e4 545 // Report back the adr ack counter
Shaun Nelson 38:182ba91524e4 546 *adrAckCounter = adrNext->AdrAckCounter;
Shaun Nelson 38:182ba91524e4 547
Shaun Nelson 38:182ba91524e4 548 if( adrNext->AdrEnabled == true )
Shaun Nelson 38:182ba91524e4 549 {
Shaun Nelson 38:182ba91524e4 550 if( datarate == CN779_TX_MIN_DATARATE )
Shaun Nelson 38:182ba91524e4 551 {
Shaun Nelson 38:182ba91524e4 552 *adrAckCounter = 0;
Shaun Nelson 38:182ba91524e4 553 adrAckReq = false;
Shaun Nelson 38:182ba91524e4 554 }
Shaun Nelson 38:182ba91524e4 555 else
Shaun Nelson 38:182ba91524e4 556 {
Shaun Nelson 38:182ba91524e4 557 if( adrNext->AdrAckCounter >= CN779_ADR_ACK_LIMIT )
Shaun Nelson 38:182ba91524e4 558 {
Shaun Nelson 38:182ba91524e4 559 adrAckReq = true;
Shaun Nelson 38:182ba91524e4 560 txPower = CN779_MAX_TX_POWER;
Shaun Nelson 38:182ba91524e4 561 }
Shaun Nelson 38:182ba91524e4 562 else
Shaun Nelson 38:182ba91524e4 563 {
Shaun Nelson 38:182ba91524e4 564 adrAckReq = false;
Shaun Nelson 38:182ba91524e4 565 }
Shaun Nelson 38:182ba91524e4 566 if( adrNext->AdrAckCounter >= ( CN779_ADR_ACK_LIMIT + CN779_ADR_ACK_DELAY ) )
Shaun Nelson 38:182ba91524e4 567 {
Shaun Nelson 38:182ba91524e4 568 if( ( adrNext->AdrAckCounter % CN779_ADR_ACK_DELAY ) == 1 )
Shaun Nelson 38:182ba91524e4 569 {
Shaun Nelson 38:182ba91524e4 570 // Decrease the datarate
Shaun Nelson 38:182ba91524e4 571 getPhy.Attribute = PHY_NEXT_LOWER_TX_DR;
Shaun Nelson 38:182ba91524e4 572 getPhy.Datarate = datarate;
Shaun Nelson 38:182ba91524e4 573 getPhy.UplinkDwellTime = adrNext->UplinkDwellTime;
Shaun Nelson 38:182ba91524e4 574 phyParam = RegionCN779GetPhyParam( &getPhy );
Shaun Nelson 38:182ba91524e4 575 datarate = phyParam.Value;
Shaun Nelson 38:182ba91524e4 576
Shaun Nelson 38:182ba91524e4 577 if( datarate == CN779_TX_MIN_DATARATE )
Shaun Nelson 38:182ba91524e4 578 {
Shaun Nelson 38:182ba91524e4 579 // We must set adrAckReq to false as soon as we reach the lowest datarate
Shaun Nelson 38:182ba91524e4 580 adrAckReq = false;
Shaun Nelson 38:182ba91524e4 581 if( adrNext->UpdateChanMask == true )
Shaun Nelson 38:182ba91524e4 582 {
Shaun Nelson 38:182ba91524e4 583 // Re-enable default channels
Shaun Nelson 38:182ba91524e4 584 ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 );
Shaun Nelson 38:182ba91524e4 585 }
Shaun Nelson 38:182ba91524e4 586 }
Shaun Nelson 38:182ba91524e4 587 }
Shaun Nelson 38:182ba91524e4 588 }
Shaun Nelson 38:182ba91524e4 589 }
Shaun Nelson 38:182ba91524e4 590 }
Shaun Nelson 38:182ba91524e4 591
Shaun Nelson 38:182ba91524e4 592 *drOut = datarate;
Shaun Nelson 38:182ba91524e4 593 *txPowOut = txPower;
Shaun Nelson 38:182ba91524e4 594 return adrAckReq;
Shaun Nelson 38:182ba91524e4 595 }
Shaun Nelson 38:182ba91524e4 596
Shaun Nelson 38:182ba91524e4 597 void RegionCN779ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams )
Shaun Nelson 38:182ba91524e4 598 {
Shaun Nelson 38:182ba91524e4 599 double tSymbol = 0.0;
Shaun Nelson 38:182ba91524e4 600
Shaun Nelson 38:182ba91524e4 601 // Get the datarate, perform a boundary check
Shaun Nelson 38:182ba91524e4 602 rxConfigParams->Datarate = MIN( datarate, CN779_RX_MAX_DATARATE );
Shaun Nelson 38:182ba91524e4 603 rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate );
Shaun Nelson 38:182ba91524e4 604
Shaun Nelson 38:182ba91524e4 605 if( rxConfigParams->Datarate == DR_7 )
Shaun Nelson 38:182ba91524e4 606 { // FSK
Shaun Nelson 38:182ba91524e4 607 tSymbol = RegionCommonComputeSymbolTimeFsk( DataratesCN779[rxConfigParams->Datarate] );
Shaun Nelson 38:182ba91524e4 608 }
Shaun Nelson 38:182ba91524e4 609 else
Shaun Nelson 38:182ba91524e4 610 { // LoRa
Shaun Nelson 38:182ba91524e4 611 tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesCN779[rxConfigParams->Datarate], BandwidthsCN779[rxConfigParams->Datarate] );
Shaun Nelson 38:182ba91524e4 612 }
Shaun Nelson 38:182ba91524e4 613
Shaun Nelson 38:182ba91524e4 614 RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset );
Shaun Nelson 38:182ba91524e4 615 }
Shaun Nelson 38:182ba91524e4 616
Shaun Nelson 38:182ba91524e4 617 bool RegionCN779RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
Shaun Nelson 38:182ba91524e4 618 {
Shaun Nelson 38:182ba91524e4 619 RadioModems_t modem;
Shaun Nelson 38:182ba91524e4 620 int8_t dr = rxConfig->Datarate;
Shaun Nelson 38:182ba91524e4 621 uint8_t maxPayload = 0;
Shaun Nelson 38:182ba91524e4 622 int8_t phyDr = 0;
Shaun Nelson 38:182ba91524e4 623 uint32_t frequency = rxConfig->Frequency;
Shaun Nelson 38:182ba91524e4 624
Shaun Nelson 38:182ba91524e4 625 if( Radio.GetStatus( ) != RF_IDLE )
Shaun Nelson 38:182ba91524e4 626 {
Shaun Nelson 38:182ba91524e4 627 return false;
Shaun Nelson 38:182ba91524e4 628 }
Shaun Nelson 38:182ba91524e4 629
Shaun Nelson 38:182ba91524e4 630 if( rxConfig->Window == 0 )
Shaun Nelson 38:182ba91524e4 631 {
Shaun Nelson 38:182ba91524e4 632 // Apply window 1 frequency
Shaun Nelson 38:182ba91524e4 633 frequency = Channels[rxConfig->Channel].Frequency;
Shaun Nelson 38:182ba91524e4 634 // Apply the alternative RX 1 window frequency, if it is available
Shaun Nelson 38:182ba91524e4 635 if( Channels[rxConfig->Channel].Rx1Frequency != 0 )
Shaun Nelson 38:182ba91524e4 636 {
Shaun Nelson 38:182ba91524e4 637 frequency = Channels[rxConfig->Channel].Rx1Frequency;
Shaun Nelson 38:182ba91524e4 638 }
Shaun Nelson 38:182ba91524e4 639 }
Shaun Nelson 38:182ba91524e4 640
Shaun Nelson 38:182ba91524e4 641 // Read the physical datarate from the datarates table
Shaun Nelson 38:182ba91524e4 642 phyDr = DataratesCN779[dr];
Shaun Nelson 38:182ba91524e4 643
Shaun Nelson 38:182ba91524e4 644 Radio.SetChannel( frequency );
Shaun Nelson 38:182ba91524e4 645
Shaun Nelson 38:182ba91524e4 646 // Radio configuration
Shaun Nelson 38:182ba91524e4 647 if( dr == DR_7 )
Shaun Nelson 38:182ba91524e4 648 {
Shaun Nelson 38:182ba91524e4 649 modem = MODEM_FSK;
Shaun Nelson 38:182ba91524e4 650 Radio.SetRxConfig( modem, 50000, phyDr * 1000, 0, 83333, 5, rxConfig->WindowTimeout, false, 0, true, 0, 0, false, rxConfig->RxContinuous );
Shaun Nelson 38:182ba91524e4 651 }
Shaun Nelson 38:182ba91524e4 652 else
Shaun Nelson 38:182ba91524e4 653 {
Shaun Nelson 38:182ba91524e4 654 modem = MODEM_LORA;
Shaun Nelson 38:182ba91524e4 655 Radio.SetRxConfig( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );
Shaun Nelson 38:182ba91524e4 656 }
Shaun Nelson 38:182ba91524e4 657
Shaun Nelson 38:182ba91524e4 658 if( rxConfig->RepeaterSupport == true )
Shaun Nelson 38:182ba91524e4 659 {
Shaun Nelson 38:182ba91524e4 660 maxPayload = MaxPayloadOfDatarateRepeaterCN779[dr];
Shaun Nelson 38:182ba91524e4 661 }
Shaun Nelson 38:182ba91524e4 662 else
Shaun Nelson 38:182ba91524e4 663 {
Shaun Nelson 38:182ba91524e4 664 maxPayload = MaxPayloadOfDatarateCN779[dr];
Shaun Nelson 38:182ba91524e4 665 }
Shaun Nelson 38:182ba91524e4 666 Radio.SetMaxPayloadLength( modem, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD );
Shaun Nelson 38:182ba91524e4 667
Shaun Nelson 38:182ba91524e4 668 *datarate = (uint8_t) dr;
Shaun Nelson 38:182ba91524e4 669 return true;
Shaun Nelson 38:182ba91524e4 670 }
Shaun Nelson 38:182ba91524e4 671
Shaun Nelson 38:182ba91524e4 672 bool RegionCN779TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir )
Shaun Nelson 38:182ba91524e4 673 {
Shaun Nelson 38:182ba91524e4 674 RadioModems_t modem;
Shaun Nelson 38:182ba91524e4 675 int8_t phyDr = DataratesCN779[txConfig->Datarate];
Shaun Nelson 38:182ba91524e4 676 int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, ChannelsMask );
Shaun Nelson 38:182ba91524e4 677 uint32_t bandwidth = GetBandwidth( txConfig->Datarate );
Shaun Nelson 38:182ba91524e4 678 int8_t phyTxPower = 0;
Shaun Nelson 38:182ba91524e4 679
Shaun Nelson 38:182ba91524e4 680 // Calculate physical TX power
Shaun Nelson 38:182ba91524e4 681 phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain );
Shaun Nelson 38:182ba91524e4 682
Shaun Nelson 38:182ba91524e4 683 // Setup the radio frequency
Shaun Nelson 38:182ba91524e4 684 Radio.SetChannel( Channels[txConfig->Channel].Frequency );
Shaun Nelson 38:182ba91524e4 685
Shaun Nelson 38:182ba91524e4 686 if( txConfig->Datarate == DR_7 )
Shaun Nelson 38:182ba91524e4 687 { // High Speed FSK channel
Shaun Nelson 38:182ba91524e4 688 modem = MODEM_FSK;
Shaun Nelson 38:182ba91524e4 689 Radio.SetTxConfig( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 3000 );
Shaun Nelson 38:182ba91524e4 690 }
Shaun Nelson 38:182ba91524e4 691 else
Shaun Nelson 38:182ba91524e4 692 {
Shaun Nelson 38:182ba91524e4 693 modem = MODEM_LORA;
Shaun Nelson 38:182ba91524e4 694 Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 );
Shaun Nelson 38:182ba91524e4 695 }
Shaun Nelson 38:182ba91524e4 696
Shaun Nelson 38:182ba91524e4 697 // Setup maximum payload lenght of the radio driver
Shaun Nelson 38:182ba91524e4 698 Radio.SetMaxPayloadLength( modem, txConfig->PktLen );
Shaun Nelson 38:182ba91524e4 699 // Get the time-on-air of the next tx frame
Shaun Nelson 38:182ba91524e4 700 *txTimeOnAir = Radio.TimeOnAir( modem, txConfig->PktLen );
Shaun Nelson 38:182ba91524e4 701
Shaun Nelson 38:182ba91524e4 702 *txPower = txPowerLimited;
Shaun Nelson 38:182ba91524e4 703 return true;
Shaun Nelson 38:182ba91524e4 704 }
Shaun Nelson 38:182ba91524e4 705
Shaun Nelson 38:182ba91524e4 706 uint8_t RegionCN779LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed )
Shaun Nelson 38:182ba91524e4 707 {
Shaun Nelson 38:182ba91524e4 708 uint8_t status = 0x07;
Shaun Nelson 38:182ba91524e4 709 RegionCommonLinkAdrParams_t linkAdrParams;
Shaun Nelson 38:182ba91524e4 710 uint8_t nextIndex = 0;
Shaun Nelson 38:182ba91524e4 711 uint8_t bytesProcessed = 0;
Shaun Nelson 38:182ba91524e4 712 uint16_t chMask = 0;
Shaun Nelson 38:182ba91524e4 713 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 714 PhyParam_t phyParam;
Shaun Nelson 38:182ba91524e4 715 RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams;
Shaun Nelson 38:182ba91524e4 716
Shaun Nelson 38:182ba91524e4 717 while( bytesProcessed < linkAdrReq->PayloadSize )
Shaun Nelson 38:182ba91524e4 718 {
Shaun Nelson 38:182ba91524e4 719 // Get ADR request parameters
Shaun Nelson 38:182ba91524e4 720 nextIndex = RegionCommonParseLinkAdrReq( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams );
Shaun Nelson 38:182ba91524e4 721
Shaun Nelson 38:182ba91524e4 722 if( nextIndex == 0 )
Shaun Nelson 38:182ba91524e4 723 break; // break loop, since no more request has been found
Shaun Nelson 38:182ba91524e4 724
Shaun Nelson 38:182ba91524e4 725 // Update bytes processed
Shaun Nelson 38:182ba91524e4 726 bytesProcessed += nextIndex;
Shaun Nelson 38:182ba91524e4 727
Shaun Nelson 38:182ba91524e4 728 // Revert status, as we only check the last ADR request for the channel mask KO
Shaun Nelson 38:182ba91524e4 729 status = 0x07;
Shaun Nelson 38:182ba91524e4 730
Shaun Nelson 38:182ba91524e4 731 // Setup temporary channels mask
Shaun Nelson 38:182ba91524e4 732 chMask = linkAdrParams.ChMask;
Shaun Nelson 38:182ba91524e4 733
Shaun Nelson 38:182ba91524e4 734 // Verify channels mask
Shaun Nelson 38:182ba91524e4 735 if( ( linkAdrParams.ChMaskCtrl == 0 ) && ( chMask == 0 ) )
Shaun Nelson 38:182ba91524e4 736 {
Shaun Nelson 38:182ba91524e4 737 status &= 0xFE; // Channel mask KO
Shaun Nelson 38:182ba91524e4 738 }
Shaun Nelson 38:182ba91524e4 739 else if( ( ( linkAdrParams.ChMaskCtrl >= 1 ) && ( linkAdrParams.ChMaskCtrl <= 5 )) ||
Shaun Nelson 38:182ba91524e4 740 ( linkAdrParams.ChMaskCtrl >= 7 ) )
Shaun Nelson 38:182ba91524e4 741 {
Shaun Nelson 38:182ba91524e4 742 // RFU
Shaun Nelson 38:182ba91524e4 743 status &= 0xFE; // Channel mask KO
Shaun Nelson 38:182ba91524e4 744 }
Shaun Nelson 38:182ba91524e4 745 else
Shaun Nelson 38:182ba91524e4 746 {
Shaun Nelson 38:182ba91524e4 747 for( uint8_t i = 0; i < CN779_MAX_NB_CHANNELS; i++ )
Shaun Nelson 38:182ba91524e4 748 {
Shaun Nelson 38:182ba91524e4 749 if( linkAdrParams.ChMaskCtrl == 6 )
Shaun Nelson 38:182ba91524e4 750 {
Shaun Nelson 38:182ba91524e4 751 if( Channels[i].Frequency != 0 )
Shaun Nelson 38:182ba91524e4 752 {
Shaun Nelson 38:182ba91524e4 753 chMask |= 1 << i;
Shaun Nelson 38:182ba91524e4 754 }
Shaun Nelson 38:182ba91524e4 755 }
Shaun Nelson 38:182ba91524e4 756 else
Shaun Nelson 38:182ba91524e4 757 {
Shaun Nelson 38:182ba91524e4 758 if( ( ( chMask & ( 1 << i ) ) != 0 ) &&
Shaun Nelson 38:182ba91524e4 759 ( Channels[i].Frequency == 0 ) )
Shaun Nelson 38:182ba91524e4 760 {// Trying to enable an undefined channel
Shaun Nelson 38:182ba91524e4 761 status &= 0xFE; // Channel mask KO
Shaun Nelson 38:182ba91524e4 762 }
Shaun Nelson 38:182ba91524e4 763 }
Shaun Nelson 38:182ba91524e4 764 }
Shaun Nelson 38:182ba91524e4 765 }
Shaun Nelson 38:182ba91524e4 766 }
Shaun Nelson 38:182ba91524e4 767
Shaun Nelson 38:182ba91524e4 768 // Get the minimum possible datarate
Shaun Nelson 38:182ba91524e4 769 getPhy.Attribute = PHY_MIN_TX_DR;
Shaun Nelson 38:182ba91524e4 770 getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime;
Shaun Nelson 38:182ba91524e4 771 phyParam = RegionCN779GetPhyParam( &getPhy );
Shaun Nelson 38:182ba91524e4 772
Shaun Nelson 38:182ba91524e4 773 linkAdrVerifyParams.Status = status;
Shaun Nelson 38:182ba91524e4 774 linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled;
Shaun Nelson 38:182ba91524e4 775 linkAdrVerifyParams.Datarate = linkAdrParams.Datarate;
Shaun Nelson 38:182ba91524e4 776 linkAdrVerifyParams.TxPower = linkAdrParams.TxPower;
Shaun Nelson 38:182ba91524e4 777 linkAdrVerifyParams.NbRep = linkAdrParams.NbRep;
Shaun Nelson 38:182ba91524e4 778 linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate;
Shaun Nelson 38:182ba91524e4 779 linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower;
Shaun Nelson 38:182ba91524e4 780 linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep;
Shaun Nelson 38:182ba91524e4 781 linkAdrVerifyParams.NbChannels = CN779_MAX_NB_CHANNELS;
Shaun Nelson 38:182ba91524e4 782 linkAdrVerifyParams.ChannelsMask = &chMask;
Shaun Nelson 38:182ba91524e4 783 linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value;
Shaun Nelson 38:182ba91524e4 784 linkAdrVerifyParams.MaxDatarate = CN779_TX_MAX_DATARATE;
Shaun Nelson 38:182ba91524e4 785 linkAdrVerifyParams.Channels = Channels;
Shaun Nelson 38:182ba91524e4 786 linkAdrVerifyParams.MinTxPower = CN779_MIN_TX_POWER;
Shaun Nelson 38:182ba91524e4 787 linkAdrVerifyParams.MaxTxPower = CN779_MAX_TX_POWER;
Shaun Nelson 38:182ba91524e4 788
Shaun Nelson 38:182ba91524e4 789 // Verify the parameters and update, if necessary
Shaun Nelson 38:182ba91524e4 790 status = RegionCommonLinkAdrReqVerifyParams( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep );
Shaun Nelson 38:182ba91524e4 791
Shaun Nelson 38:182ba91524e4 792 // Update channelsMask if everything is correct
Shaun Nelson 38:182ba91524e4 793 if( status == 0x07 )
Shaun Nelson 38:182ba91524e4 794 {
Shaun Nelson 38:182ba91524e4 795 // Set the channels mask to a default value
Shaun Nelson 38:182ba91524e4 796 memset( ChannelsMask, 0, sizeof( ChannelsMask ) );
Shaun Nelson 38:182ba91524e4 797 // Update the channels mask
Shaun Nelson 38:182ba91524e4 798 ChannelsMask[0] = chMask;
Shaun Nelson 38:182ba91524e4 799 }
Shaun Nelson 38:182ba91524e4 800
Shaun Nelson 38:182ba91524e4 801 // Update status variables
Shaun Nelson 38:182ba91524e4 802 *drOut = linkAdrParams.Datarate;
Shaun Nelson 38:182ba91524e4 803 *txPowOut = linkAdrParams.TxPower;
Shaun Nelson 38:182ba91524e4 804 *nbRepOut = linkAdrParams.NbRep;
Shaun Nelson 38:182ba91524e4 805 *nbBytesParsed = bytesProcessed;
Shaun Nelson 38:182ba91524e4 806
Shaun Nelson 38:182ba91524e4 807 return status;
Shaun Nelson 38:182ba91524e4 808 }
Shaun Nelson 38:182ba91524e4 809
Shaun Nelson 38:182ba91524e4 810 uint8_t RegionCN779RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq )
Shaun Nelson 38:182ba91524e4 811 {
Shaun Nelson 38:182ba91524e4 812 uint8_t status = 0x07;
Shaun Nelson 38:182ba91524e4 813
Shaun Nelson 38:182ba91524e4 814 // Verify radio frequency
Shaun Nelson 38:182ba91524e4 815 if( Radio.CheckRfFrequency( rxParamSetupReq->Frequency ) == false )
Shaun Nelson 38:182ba91524e4 816 {
Shaun Nelson 38:182ba91524e4 817 status &= 0xFE; // Channel frequency KO
Shaun Nelson 38:182ba91524e4 818 }
Shaun Nelson 38:182ba91524e4 819
Shaun Nelson 38:182ba91524e4 820 // Verify datarate
Shaun Nelson 38:182ba91524e4 821 if( RegionCommonValueInRange( rxParamSetupReq->Datarate, CN779_RX_MIN_DATARATE, CN779_RX_MAX_DATARATE ) == false )
Shaun Nelson 38:182ba91524e4 822 {
Shaun Nelson 38:182ba91524e4 823 status &= 0xFD; // Datarate KO
Shaun Nelson 38:182ba91524e4 824 }
Shaun Nelson 38:182ba91524e4 825
Shaun Nelson 38:182ba91524e4 826 // Verify datarate offset
Shaun Nelson 38:182ba91524e4 827 if( RegionCommonValueInRange( rxParamSetupReq->DrOffset, CN779_MIN_RX1_DR_OFFSET, CN779_MAX_RX1_DR_OFFSET ) == false )
Shaun Nelson 38:182ba91524e4 828 {
Shaun Nelson 38:182ba91524e4 829 status &= 0xFB; // Rx1DrOffset range KO
Shaun Nelson 38:182ba91524e4 830 }
Shaun Nelson 38:182ba91524e4 831
Shaun Nelson 38:182ba91524e4 832 return status;
Shaun Nelson 38:182ba91524e4 833 }
Shaun Nelson 38:182ba91524e4 834
Shaun Nelson 38:182ba91524e4 835 uint8_t RegionCN779NewChannelReq( NewChannelReqParams_t* newChannelReq )
Shaun Nelson 38:182ba91524e4 836 {
Shaun Nelson 38:182ba91524e4 837 uint8_t status = 0x03;
Shaun Nelson 38:182ba91524e4 838 ChannelAddParams_t channelAdd;
Shaun Nelson 38:182ba91524e4 839 ChannelRemoveParams_t channelRemove;
Shaun Nelson 38:182ba91524e4 840
Shaun Nelson 38:182ba91524e4 841 if( newChannelReq->NewChannel->Frequency == 0 )
Shaun Nelson 38:182ba91524e4 842 {
Shaun Nelson 38:182ba91524e4 843 channelRemove.ChannelId = newChannelReq->ChannelId;
Shaun Nelson 38:182ba91524e4 844
Shaun Nelson 38:182ba91524e4 845 // Remove
Shaun Nelson 38:182ba91524e4 846 if( RegionCN779ChannelsRemove( &channelRemove ) == false )
Shaun Nelson 38:182ba91524e4 847 {
Shaun Nelson 38:182ba91524e4 848 status &= 0xFC;
Shaun Nelson 38:182ba91524e4 849 }
Shaun Nelson 38:182ba91524e4 850 }
Shaun Nelson 38:182ba91524e4 851 else
Shaun Nelson 38:182ba91524e4 852 {
Shaun Nelson 38:182ba91524e4 853 channelAdd.NewChannel = newChannelReq->NewChannel;
Shaun Nelson 38:182ba91524e4 854 channelAdd.ChannelId = newChannelReq->ChannelId;
Shaun Nelson 38:182ba91524e4 855
Shaun Nelson 38:182ba91524e4 856 switch( RegionCN779ChannelAdd( &channelAdd ) )
Shaun Nelson 38:182ba91524e4 857 {
Shaun Nelson 38:182ba91524e4 858 case LORAMAC_STATUS_OK:
Shaun Nelson 38:182ba91524e4 859 {
Shaun Nelson 38:182ba91524e4 860 break;
Shaun Nelson 38:182ba91524e4 861 }
Shaun Nelson 38:182ba91524e4 862 case LORAMAC_STATUS_FREQUENCY_INVALID:
Shaun Nelson 38:182ba91524e4 863 {
Shaun Nelson 38:182ba91524e4 864 status &= 0xFE;
Shaun Nelson 38:182ba91524e4 865 break;
Shaun Nelson 38:182ba91524e4 866 }
Shaun Nelson 38:182ba91524e4 867 case LORAMAC_STATUS_DATARATE_INVALID:
Shaun Nelson 38:182ba91524e4 868 {
Shaun Nelson 38:182ba91524e4 869 status &= 0xFD;
Shaun Nelson 38:182ba91524e4 870 break;
Shaun Nelson 38:182ba91524e4 871 }
Shaun Nelson 38:182ba91524e4 872 case LORAMAC_STATUS_FREQ_AND_DR_INVALID:
Shaun Nelson 38:182ba91524e4 873 {
Shaun Nelson 38:182ba91524e4 874 status &= 0xFC;
Shaun Nelson 38:182ba91524e4 875 break;
Shaun Nelson 38:182ba91524e4 876 }
Shaun Nelson 38:182ba91524e4 877 default:
Shaun Nelson 38:182ba91524e4 878 {
Shaun Nelson 38:182ba91524e4 879 status &= 0xFC;
Shaun Nelson 38:182ba91524e4 880 break;
Shaun Nelson 38:182ba91524e4 881 }
Shaun Nelson 38:182ba91524e4 882 }
Shaun Nelson 38:182ba91524e4 883 }
Shaun Nelson 38:182ba91524e4 884
Shaun Nelson 38:182ba91524e4 885 return status;
Shaun Nelson 38:182ba91524e4 886 }
Shaun Nelson 38:182ba91524e4 887
Shaun Nelson 38:182ba91524e4 888 int8_t RegionCN779TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq )
Shaun Nelson 38:182ba91524e4 889 {
Shaun Nelson 38:182ba91524e4 890 return -1;
Shaun Nelson 38:182ba91524e4 891 }
Shaun Nelson 38:182ba91524e4 892
Shaun Nelson 38:182ba91524e4 893 uint8_t RegionCN779DlChannelReq( DlChannelReqParams_t* dlChannelReq )
Shaun Nelson 38:182ba91524e4 894 {
Shaun Nelson 38:182ba91524e4 895 uint8_t status = 0x03;
Shaun Nelson 38:182ba91524e4 896
Shaun Nelson 38:182ba91524e4 897 // Verify if the frequency is supported
Shaun Nelson 38:182ba91524e4 898 if( VerifyTxFreq( dlChannelReq->Rx1Frequency ) == false )
Shaun Nelson 38:182ba91524e4 899 {
Shaun Nelson 38:182ba91524e4 900 status &= 0xFE;
Shaun Nelson 38:182ba91524e4 901 }
Shaun Nelson 38:182ba91524e4 902
Shaun Nelson 38:182ba91524e4 903 // Verify if an uplink frequency exists
Shaun Nelson 38:182ba91524e4 904 if( Channels[dlChannelReq->ChannelId].Frequency == 0 )
Shaun Nelson 38:182ba91524e4 905 {
Shaun Nelson 38:182ba91524e4 906 status &= 0xFD;
Shaun Nelson 38:182ba91524e4 907 }
Shaun Nelson 38:182ba91524e4 908
Shaun Nelson 38:182ba91524e4 909 // Apply Rx1 frequency, if the status is OK
Shaun Nelson 38:182ba91524e4 910 if( status == 0x03 )
Shaun Nelson 38:182ba91524e4 911 {
Shaun Nelson 38:182ba91524e4 912 Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency;
Shaun Nelson 38:182ba91524e4 913 }
Shaun Nelson 38:182ba91524e4 914
Shaun Nelson 38:182ba91524e4 915 return status;
Shaun Nelson 38:182ba91524e4 916 }
Shaun Nelson 38:182ba91524e4 917
Shaun Nelson 38:182ba91524e4 918 int8_t RegionCN779AlternateDr( AlternateDrParams_t* alternateDr )
Shaun Nelson 38:182ba91524e4 919 {
Shaun Nelson 38:182ba91524e4 920 int8_t datarate = 0;
Shaun Nelson 38:182ba91524e4 921
Shaun Nelson 38:182ba91524e4 922 if( ( alternateDr->NbTrials % 48 ) == 0 )
Shaun Nelson 38:182ba91524e4 923 {
Shaun Nelson 38:182ba91524e4 924 datarate = DR_0;
Shaun Nelson 38:182ba91524e4 925 }
Shaun Nelson 38:182ba91524e4 926 else if( ( alternateDr->NbTrials % 32 ) == 0 )
Shaun Nelson 38:182ba91524e4 927 {
Shaun Nelson 38:182ba91524e4 928 datarate = DR_1;
Shaun Nelson 38:182ba91524e4 929 }
Shaun Nelson 38:182ba91524e4 930 else if( ( alternateDr->NbTrials % 24 ) == 0 )
Shaun Nelson 38:182ba91524e4 931 {
Shaun Nelson 38:182ba91524e4 932 datarate = DR_2;
Shaun Nelson 38:182ba91524e4 933 }
Shaun Nelson 38:182ba91524e4 934 else if( ( alternateDr->NbTrials % 16 ) == 0 )
Shaun Nelson 38:182ba91524e4 935 {
Shaun Nelson 38:182ba91524e4 936 datarate = DR_3;
Shaun Nelson 38:182ba91524e4 937 }
Shaun Nelson 38:182ba91524e4 938 else if( ( alternateDr->NbTrials % 8 ) == 0 )
Shaun Nelson 38:182ba91524e4 939 {
Shaun Nelson 38:182ba91524e4 940 datarate = DR_4;
Shaun Nelson 38:182ba91524e4 941 }
Shaun Nelson 38:182ba91524e4 942 else
Shaun Nelson 38:182ba91524e4 943 {
Shaun Nelson 38:182ba91524e4 944 datarate = DR_5;
Shaun Nelson 38:182ba91524e4 945 }
Shaun Nelson 38:182ba91524e4 946 return datarate;
Shaun Nelson 38:182ba91524e4 947 }
Shaun Nelson 38:182ba91524e4 948
Shaun Nelson 38:182ba91524e4 949 void RegionCN779CalcBackOff( CalcBackOffParams_t* calcBackOff )
Shaun Nelson 38:182ba91524e4 950 {
Shaun Nelson 38:182ba91524e4 951 RegionCommonCalcBackOffParams_t calcBackOffParams;
Shaun Nelson 38:182ba91524e4 952
Shaun Nelson 38:182ba91524e4 953 calcBackOffParams.Channels = Channels;
Shaun Nelson 38:182ba91524e4 954 calcBackOffParams.Bands = Bands;
Shaun Nelson 38:182ba91524e4 955 calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest;
Shaun Nelson 38:182ba91524e4 956 calcBackOffParams.Joined = calcBackOff->Joined;
Shaun Nelson 38:182ba91524e4 957 calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled;
Shaun Nelson 38:182ba91524e4 958 calcBackOffParams.Channel = calcBackOff->Channel;
Shaun Nelson 38:182ba91524e4 959 calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime;
Shaun Nelson 38:182ba91524e4 960 calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir;
Shaun Nelson 38:182ba91524e4 961
Shaun Nelson 38:182ba91524e4 962 RegionCommonCalcBackOff( &calcBackOffParams );
Shaun Nelson 38:182ba91524e4 963 }
Shaun Nelson 38:182ba91524e4 964
Shaun Nelson 38:182ba91524e4 965 bool RegionCN779NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff )
Shaun Nelson 38:182ba91524e4 966 {
Shaun Nelson 38:182ba91524e4 967 uint8_t nbEnabledChannels = 0;
Shaun Nelson 38:182ba91524e4 968 uint8_t delayTx = 0;
Shaun Nelson 38:182ba91524e4 969 uint8_t enabledChannels[CN779_MAX_NB_CHANNELS] = { 0 };
Shaun Nelson 38:182ba91524e4 970 TimerTime_t nextTxDelay = 0;
Shaun Nelson 38:182ba91524e4 971
Shaun Nelson 38:182ba91524e4 972 if( RegionCommonCountChannels( ChannelsMask, 0, 1 ) == 0 )
Shaun Nelson 38:182ba91524e4 973 { // Reactivate default channels
Shaun Nelson 38:182ba91524e4 974 ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 );
Shaun Nelson 38:182ba91524e4 975 }
Shaun Nelson 38:182ba91524e4 976
Shaun Nelson 38:182ba91524e4 977 if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) )
Shaun Nelson 38:182ba91524e4 978 {
Shaun Nelson 38:182ba91524e4 979 // Reset Aggregated time off
Shaun Nelson 38:182ba91524e4 980 *aggregatedTimeOff = 0;
Shaun Nelson 38:182ba91524e4 981
Shaun Nelson 38:182ba91524e4 982 // Update bands Time OFF
Shaun Nelson 38:182ba91524e4 983 nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, Bands, CN779_MAX_NB_BANDS );
Shaun Nelson 38:182ba91524e4 984
Shaun Nelson 38:182ba91524e4 985 // Search how many channels are enabled
Shaun Nelson 38:182ba91524e4 986 nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Joined, nextChanParams->Datarate,
Shaun Nelson 38:182ba91524e4 987 ChannelsMask, Channels,
Shaun Nelson 38:182ba91524e4 988 Bands, enabledChannels, &delayTx );
Shaun Nelson 38:182ba91524e4 989 }
Shaun Nelson 38:182ba91524e4 990 else
Shaun Nelson 38:182ba91524e4 991 {
Shaun Nelson 38:182ba91524e4 992 delayTx++;
Shaun Nelson 38:182ba91524e4 993 nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx );
Shaun Nelson 38:182ba91524e4 994 }
Shaun Nelson 38:182ba91524e4 995
Shaun Nelson 38:182ba91524e4 996 if( nbEnabledChannels > 0 )
Shaun Nelson 38:182ba91524e4 997 {
Shaun Nelson 38:182ba91524e4 998 // We found a valid channel
Shaun Nelson 38:182ba91524e4 999 *channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];
Shaun Nelson 38:182ba91524e4 1000
Shaun Nelson 38:182ba91524e4 1001 *time = 0;
Shaun Nelson 38:182ba91524e4 1002 return true;
Shaun Nelson 38:182ba91524e4 1003 }
Shaun Nelson 38:182ba91524e4 1004 else
Shaun Nelson 38:182ba91524e4 1005 {
Shaun Nelson 38:182ba91524e4 1006 if( delayTx > 0 )
Shaun Nelson 38:182ba91524e4 1007 {
Shaun Nelson 38:182ba91524e4 1008 // Delay transmission due to AggregatedTimeOff or to a band time off
Shaun Nelson 38:182ba91524e4 1009 *time = nextTxDelay;
Shaun Nelson 38:182ba91524e4 1010 return true;
Shaun Nelson 38:182ba91524e4 1011 }
Shaun Nelson 38:182ba91524e4 1012 // Datarate not supported by any channel, restore defaults
Shaun Nelson 38:182ba91524e4 1013 ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 );
Shaun Nelson 38:182ba91524e4 1014 *time = 0;
Shaun Nelson 38:182ba91524e4 1015 return false;
Shaun Nelson 38:182ba91524e4 1016 }
Shaun Nelson 38:182ba91524e4 1017 }
Shaun Nelson 38:182ba91524e4 1018
Shaun Nelson 38:182ba91524e4 1019 LoRaMacStatus_t RegionCN779ChannelAdd( ChannelAddParams_t* channelAdd )
Shaun Nelson 38:182ba91524e4 1020 {
Shaun Nelson 38:182ba91524e4 1021 uint8_t band = 0;
Shaun Nelson 38:182ba91524e4 1022 bool drInvalid = false;
Shaun Nelson 38:182ba91524e4 1023 bool freqInvalid = false;
Shaun Nelson 38:182ba91524e4 1024 uint8_t id = channelAdd->ChannelId;
Shaun Nelson 38:182ba91524e4 1025
Shaun Nelson 38:182ba91524e4 1026 if( id >= CN779_MAX_NB_CHANNELS )
Shaun Nelson 38:182ba91524e4 1027 {
Shaun Nelson 38:182ba91524e4 1028 return LORAMAC_STATUS_PARAMETER_INVALID;
Shaun Nelson 38:182ba91524e4 1029 }
Shaun Nelson 38:182ba91524e4 1030
Shaun Nelson 38:182ba91524e4 1031 // Validate the datarate range
Shaun Nelson 38:182ba91524e4 1032 if( RegionCommonValueInRange( channelAdd->NewChannel->DrRange.Fields.Min, CN779_TX_MIN_DATARATE, CN779_TX_MAX_DATARATE ) == false )
Shaun Nelson 38:182ba91524e4 1033 {
Shaun Nelson 38:182ba91524e4 1034 drInvalid = true;
Shaun Nelson 38:182ba91524e4 1035 }
Shaun Nelson 38:182ba91524e4 1036 if( RegionCommonValueInRange( channelAdd->NewChannel->DrRange.Fields.Max, CN779_TX_MIN_DATARATE, CN779_TX_MAX_DATARATE ) == false )
Shaun Nelson 38:182ba91524e4 1037 {
Shaun Nelson 38:182ba91524e4 1038 drInvalid = true;
Shaun Nelson 38:182ba91524e4 1039 }
Shaun Nelson 38:182ba91524e4 1040 if( channelAdd->NewChannel->DrRange.Fields.Min > channelAdd->NewChannel->DrRange.Fields.Max )
Shaun Nelson 38:182ba91524e4 1041 {
Shaun Nelson 38:182ba91524e4 1042 drInvalid = true;
Shaun Nelson 38:182ba91524e4 1043 }
Shaun Nelson 38:182ba91524e4 1044
Shaun Nelson 38:182ba91524e4 1045 // Default channels don't accept all values
Shaun Nelson 38:182ba91524e4 1046 if( id < CN779_NUMB_DEFAULT_CHANNELS )
Shaun Nelson 38:182ba91524e4 1047 {
Shaun Nelson 38:182ba91524e4 1048 // Validate the datarate range for min: must be DR_0
Shaun Nelson 38:182ba91524e4 1049 if( channelAdd->NewChannel->DrRange.Fields.Min > DR_0 )
Shaun Nelson 38:182ba91524e4 1050 {
Shaun Nelson 38:182ba91524e4 1051 drInvalid = true;
Shaun Nelson 38:182ba91524e4 1052 }
Shaun Nelson 38:182ba91524e4 1053 // Validate the datarate range for max: must be DR_5 <= Max <= TX_MAX_DATARATE
Shaun Nelson 38:182ba91524e4 1054 if( RegionCommonValueInRange( channelAdd->NewChannel->DrRange.Fields.Max, DR_5, CN779_TX_MAX_DATARATE ) == false )
Shaun Nelson 38:182ba91524e4 1055 {
Shaun Nelson 38:182ba91524e4 1056 drInvalid = true;
Shaun Nelson 38:182ba91524e4 1057 }
Shaun Nelson 38:182ba91524e4 1058 // We are not allowed to change the frequency
Shaun Nelson 38:182ba91524e4 1059 if( channelAdd->NewChannel->Frequency != Channels[id].Frequency )
Shaun Nelson 38:182ba91524e4 1060 {
Shaun Nelson 38:182ba91524e4 1061 freqInvalid = true;
Shaun Nelson 38:182ba91524e4 1062 }
Shaun Nelson 38:182ba91524e4 1063 }
Shaun Nelson 38:182ba91524e4 1064
Shaun Nelson 38:182ba91524e4 1065 // Check frequency
Shaun Nelson 38:182ba91524e4 1066 if( freqInvalid == false )
Shaun Nelson 38:182ba91524e4 1067 {
Shaun Nelson 38:182ba91524e4 1068 if( VerifyTxFreq( channelAdd->NewChannel->Frequency ) == false )
Shaun Nelson 38:182ba91524e4 1069 {
Shaun Nelson 38:182ba91524e4 1070 freqInvalid = true;
Shaun Nelson 38:182ba91524e4 1071 }
Shaun Nelson 38:182ba91524e4 1072 }
Shaun Nelson 38:182ba91524e4 1073
Shaun Nelson 38:182ba91524e4 1074 // Check status
Shaun Nelson 38:182ba91524e4 1075 if( ( drInvalid == true ) && ( freqInvalid == true ) )
Shaun Nelson 38:182ba91524e4 1076 {
Shaun Nelson 38:182ba91524e4 1077 return LORAMAC_STATUS_FREQ_AND_DR_INVALID;
Shaun Nelson 38:182ba91524e4 1078 }
Shaun Nelson 38:182ba91524e4 1079 if( drInvalid == true )
Shaun Nelson 38:182ba91524e4 1080 {
Shaun Nelson 38:182ba91524e4 1081 return LORAMAC_STATUS_DATARATE_INVALID;
Shaun Nelson 38:182ba91524e4 1082 }
Shaun Nelson 38:182ba91524e4 1083 if( freqInvalid == true )
Shaun Nelson 38:182ba91524e4 1084 {
Shaun Nelson 38:182ba91524e4 1085 return LORAMAC_STATUS_FREQUENCY_INVALID;
Shaun Nelson 38:182ba91524e4 1086 }
Shaun Nelson 38:182ba91524e4 1087
Shaun Nelson 38:182ba91524e4 1088 memcpy( &(Channels[id]), channelAdd->NewChannel, sizeof( Channels[id] ) );
Shaun Nelson 38:182ba91524e4 1089 Channels[id].Band = band;
Shaun Nelson 38:182ba91524e4 1090 ChannelsMask[0] |= ( 1 << id );
Shaun Nelson 38:182ba91524e4 1091 return LORAMAC_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1092 }
Shaun Nelson 38:182ba91524e4 1093
Shaun Nelson 38:182ba91524e4 1094 bool RegionCN779ChannelsRemove( ChannelRemoveParams_t* channelRemove )
Shaun Nelson 38:182ba91524e4 1095 {
Shaun Nelson 38:182ba91524e4 1096 uint8_t id = channelRemove->ChannelId;
Shaun Nelson 38:182ba91524e4 1097
Shaun Nelson 38:182ba91524e4 1098 if( id < CN779_NUMB_DEFAULT_CHANNELS )
Shaun Nelson 38:182ba91524e4 1099 {
Shaun Nelson 38:182ba91524e4 1100 return false;
Shaun Nelson 38:182ba91524e4 1101 }
Shaun Nelson 38:182ba91524e4 1102
Shaun Nelson 38:182ba91524e4 1103 // Remove the channel from the list of channels
Shaun Nelson 38:182ba91524e4 1104 Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 };
Shaun Nelson 38:182ba91524e4 1105
Shaun Nelson 38:182ba91524e4 1106 return RegionCommonChanDisable( ChannelsMask, id, CN779_MAX_NB_CHANNELS );
Shaun Nelson 38:182ba91524e4 1107 }
Shaun Nelson 38:182ba91524e4 1108
Shaun Nelson 38:182ba91524e4 1109 void RegionCN779SetContinuousWave( ContinuousWaveParams_t* continuousWave )
Shaun Nelson 38:182ba91524e4 1110 {
Shaun Nelson 38:182ba91524e4 1111 int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, ChannelsMask );
Shaun Nelson 38:182ba91524e4 1112 int8_t phyTxPower = 0;
Shaun Nelson 38:182ba91524e4 1113 uint32_t frequency = Channels[continuousWave->Channel].Frequency;
Shaun Nelson 38:182ba91524e4 1114
Shaun Nelson 38:182ba91524e4 1115 // Calculate physical TX power
Shaun Nelson 38:182ba91524e4 1116 phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain );
Shaun Nelson 38:182ba91524e4 1117
Shaun Nelson 38:182ba91524e4 1118 Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout );
Shaun Nelson 38:182ba91524e4 1119 }
Shaun Nelson 38:182ba91524e4 1120
Shaun Nelson 38:182ba91524e4 1121 uint8_t RegionCN779ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset )
Shaun Nelson 38:182ba91524e4 1122 {
Shaun Nelson 38:182ba91524e4 1123 int8_t datarate = dr - drOffset;
Shaun Nelson 38:182ba91524e4 1124
Shaun Nelson 38:182ba91524e4 1125 if( datarate < 0 )
Shaun Nelson 38:182ba91524e4 1126 {
Shaun Nelson 38:182ba91524e4 1127 datarate = DR_0;
Shaun Nelson 38:182ba91524e4 1128 }
Shaun Nelson 38:182ba91524e4 1129 return datarate;
Shaun Nelson 38:182ba91524e4 1130 }
Shaun Nelson 38:182ba91524e4 1131
Shaun Nelson 38:182ba91524e4 1132 void RegionCN779RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr, bool *beaconChannelSet )
Shaun Nelson 38:182ba91524e4 1133 {
Shaun Nelson 38:182ba91524e4 1134 RegionCommonRxBeaconSetupParams_t regionCommonRxBeaconSetup;
Shaun Nelson 38:182ba91524e4 1135
Shaun Nelson 38:182ba91524e4 1136 regionCommonRxBeaconSetup.Datarates = DataratesCN779;
Shaun Nelson 38:182ba91524e4 1137 regionCommonRxBeaconSetup.ChannelPlanFrequency = CN779_BEACON_CHANNEL_FREQ;
Shaun Nelson 38:182ba91524e4 1138 regionCommonRxBeaconSetup.BeaconTimingAnsFrequency = CN779_BEACON_CHANNEL_FREQ;
Shaun Nelson 38:182ba91524e4 1139 regionCommonRxBeaconSetup.BeaconSize = CN779_BEACON_SIZE;
Shaun Nelson 38:182ba91524e4 1140 regionCommonRxBeaconSetup.BeaconDatarate = CN779_BEACON_CHANNEL_DR;
Shaun Nelson 38:182ba91524e4 1141 regionCommonRxBeaconSetup.BeaconChannelBW = CN779_BEACON_CHANNEL_BW;
Shaun Nelson 38:182ba91524e4 1142 regionCommonRxBeaconSetup.CustomFrequency = rxBeaconSetup->CustomFrequency;
Shaun Nelson 38:182ba91524e4 1143 regionCommonRxBeaconSetup.CustomFrequencyEnabled = rxBeaconSetup->CustomFrequencyEnabled;
Shaun Nelson 38:182ba91524e4 1144 regionCommonRxBeaconSetup.BeaconChannelSet = rxBeaconSetup->BeaconChannelSet;
Shaun Nelson 38:182ba91524e4 1145 regionCommonRxBeaconSetup.RxTime = rxBeaconSetup->RxTime;
Shaun Nelson 38:182ba91524e4 1146 regionCommonRxBeaconSetup.SymbolTimeout = rxBeaconSetup->SymbolTimeout;
Shaun Nelson 38:182ba91524e4 1147
Shaun Nelson 38:182ba91524e4 1148 RegionCommonRxBeaconSetup( &regionCommonRxBeaconSetup, beaconChannelSet );
Shaun Nelson 38:182ba91524e4 1149
Shaun Nelson 38:182ba91524e4 1150 // Store downlink datarate
Shaun Nelson 38:182ba91524e4 1151 *outDr = CN779_BEACON_CHANNEL_DR;
Shaun Nelson 38:182ba91524e4 1152 }