1 /*!
2 * \file RegionCN470B20.c
3 *
4 * \brief
5 *
6 * \copyright Revised BSD License, see section \ref LICENSE.
7 *
8 * \code
9 * ______ _
10 * / _____) _ | |
11 * ( (____ _____ ____ _| |_ _____ ____| |__
12 * \____ \| ___ | (_ _) ___ |/ ___) _ \
13 * _____) ) ____| | | || |_| ____( (___| | | |
14 * (______/|_____)_|_|_| \__)_____)\____)_| |_|
15 * (C)2013-2017 Semtech
16 *
17 * ___ _____ _ ___ _ _____ ___ ___ ___ ___
18 * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
19 * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
20 * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
21 * embedded.connectivity.solutions===============
22 *
23 * \endcode
24 *
25 * \author Miguel Luis ( Semtech )
26 *
27 * \author Daniel Jaeckle ( STACKFORCE )
28 *
29 * \defgroup REGIONCN470
30 */
31 #include "RegionCN470.h"
32 #include "RegionBaseUS.h"
33 #include "RegionCN470B20.h"
34 #include "RegionCN470A20.h"
35
RegionCN470B20GetDownlinkFrequency(uint8_t channel,uint8_t joinChannelIndex,bool isPingSlot)36 uint32_t RegionCN470B20GetDownlinkFrequency( uint8_t channel, uint8_t joinChannelIndex, bool isPingSlot )
37 {
38 if( isPingSlot == true)
39 {
40 return RegionCN470B20GetRx1Frequency( channel );
41 }
42 else
43 {
44 if( joinChannelIndex == 8 )
45 {
46 return RegionCN470B20GetRx1Frequency( 23 );
47 }
48 else
49 {
50 return RegionCN470B20GetRx1Frequency( 55 );
51 }
52 }
53 }
54
RegionCN470B20GetBeaconChannelOffset(uint8_t joinChannelIndex)55 uint8_t RegionCN470B20GetBeaconChannelOffset( uint8_t joinChannelIndex )
56 {
57 return ( joinChannelIndex - 8 ) * 32;
58 }
59
RegionCN470B20LinkAdrChMaskUpdate(uint16_t * channelsMask,uint8_t chMaskCntl,uint16_t chanMask,ChannelParams_t * channels)60 uint8_t RegionCN470B20LinkAdrChMaskUpdate( uint16_t* channelsMask, uint8_t chMaskCntl,
61 uint16_t chanMask, ChannelParams_t* channels )
62 {
63 // It follows the same implementation as type A
64 return RegionCN470A20LinkAdrChMaskUpdate( channelsMask, chMaskCntl,
65 chanMask, channels );
66 }
67
RegionCN470B20VerifyRfFreq(uint32_t freq)68 bool RegionCN470B20VerifyRfFreq( uint32_t freq )
69 {
70 bool group1Status = false;
71 bool group2Status = false;
72
73 // Downstream group 1
74 group1Status = RegionBaseUSVerifyFrequencyGroup( freq, CN470_B20_FIRST_RX1_CHANNEL,
75 CN470_B20_LAST_RX1_CHANNEL,
76 CN470_B20_STEPWIDTH_RX1_CHANNEL );
77 // Downstream group 2
78 group2Status = RegionBaseUSVerifyFrequencyGroup( freq, CN470_B20_FIRST_RX2_CHANNEL,
79 CN470_B20_LAST_RX2_CHANNEL,
80 CN470_B20_STEPWIDTH_RX2_CHANNEL );
81
82 // The frequency must be available in one of the groups
83 if( ( group1Status == false ) && ( group2Status == false ) )
84 {
85 return false;
86 }
87 return true;
88 }
89
RegionCN470B20InitializeChannels(ChannelParams_t * channels)90 void RegionCN470B20InitializeChannels( ChannelParams_t* channels )
91 {
92 // Upstream group 1
93 for( uint8_t i = 0; i < 32; i++ )
94 {
95 channels[i].Frequency = CN470_B20_FIRST_TX1_CHANNEL + i * CN470_B20_STEPWIDTH_TX1_CHANNEL;
96 channels[i].DrRange.Value = ( CN470_TX_MAX_DATARATE << 4 ) | CN470_TX_MIN_DATARATE;
97 channels[i].Band = 0;
98 }
99 // Upstream group 2
100 for( uint8_t i = 32; i < 64; i++ )
101 {
102 channels[i].Frequency = CN470_B20_FIRST_TX2_CHANNEL + ( i - 32 ) * CN470_B20_STEPWIDTH_TX2_CHANNEL;
103 channels[i].DrRange.Value = ( CN470_TX_MAX_DATARATE << 4 ) | CN470_TX_MIN_DATARATE;
104 channels[i].Band = 0;
105 }
106 }
107
RegionCN470B20InitializeChannelsMask(uint16_t * channelsDefaultMask)108 void RegionCN470B20InitializeChannelsMask( uint16_t* channelsDefaultMask )
109 {
110 RegionCN470A20InitializeChannelsMask( channelsDefaultMask );
111 }
112
RegionCN470B20GetRx1Frequency(uint8_t channel)113 uint32_t RegionCN470B20GetRx1Frequency( uint8_t channel )
114 {
115 // Base frequency for downstream group 1
116 uint32_t baseFrequency = CN470_B20_FIRST_RX1_CHANNEL;
117 uint8_t offset = 0;
118
119 if( channel >= 32 )
120 {
121 // Base frequency for downstream group 2
122 baseFrequency = CN470_B20_FIRST_RX2_CHANNEL;
123 offset = 32;
124 }
125 return ( baseFrequency + ( ( channel - offset ) * CN470_B20_STEPWIDTH_RX1_CHANNEL ) );
126 }
127
RegionCN470B20GetRx2Frequency(uint8_t joinChannelIndex,bool isOtaaDevice)128 uint32_t RegionCN470B20GetRx2Frequency( uint8_t joinChannelIndex, bool isOtaaDevice )
129 {
130 uint32_t otaaFrequencies[] = CN470_B20_RX_WND_2_FREQ_OTAA;
131
132 if( isOtaaDevice == true )
133 {
134 return otaaFrequencies[joinChannelIndex - 8];
135 }
136 // ABP device
137 return CN470_B20_RX_WND_2_FREQ_ABP;
138 }
139
140