blob: 94a96d3be943adeb328895345a867e5324337286 [file] [log] [blame]
Wei-Yu Chen49950b92021-11-08 19:19:18 +08001"""
2Copyright 2020 The Magma Authors.
3
4This source code is licensed under the BSD-style license found in the
5LICENSE file in the root directory of this source tree.
6
7Unless required by applicable law or agreed to in writing, software
8distributed under the License is distributed on an "AS IS" BASIS,
9WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10See the License for the specific language governing permissions and
11limitations under the License.
12"""
13
14from enum import Enum
15from typing import Optional
16
17
18class DuplexMode(Enum):
19 FDD = 1
20 TDD = 2
21
22
23class LTEBandInfo:
24 """ Class for holding information related to LTE band.
25 Takes advantage of the following properties of LTE EARFCN assignment:
26 - EARFCN spacing within a band is always 0.1MHz
27 - 1:1 mapping between EARFCNDL and EARFCNUL (for FDD)
28 """
29
30 def __init__(
31 self, duplex_mode, earfcndl, start_freq_dl_mhz,
32 start_earfcnul=None, start_freq_ul_mhz=None,
33 ):
34 """
35 Inputs:
36 - Duplex mode - type = DuplexMode
37 - earfcndl - List/generator of integer EARFCNDLs in band, from lowest to
38 highest
39 - start_freq_dl_mhz - Frequency of lowest numbered EARFCNDL in band
40 (MHz)
41 - start_earfcnul - Lowest numbered EARFCNUL in band
42 (or None if band is TDD)
43 - start_freq_ul_mhz - Frequency of lowest numbered EARFCNUL in band
44 (MHz) (or None if band is TDD)
45 """
46 # Validate inputs
47 assert type(earfcndl) == list or type(earfcndl) == range
48 assert type(start_freq_dl_mhz) == int
49 assert type(duplex_mode) == DuplexMode
50 if duplex_mode == DuplexMode.FDD:
51 assert type(start_earfcnul) == int
52 assert type(start_freq_ul_mhz) == int
53 else:
54 assert start_earfcnul is None
55 assert start_freq_ul_mhz is None
56
57 # DuplexMode.TDD or DuplexMode.FDD
58 self.duplex_mode = duplex_mode
59 # Array of EARFCNDL values
60 self.earfcndl = earfcndl
61 # Array of DL frequencies in MHz, one per EARFCNDL
62 self.freq_mhz_dl = [
63 start_freq_dl_mhz + 0.1 * (earfcn - earfcndl[0])
64 for earfcn in earfcndl
65 ]
66
67 if duplex_mode == DuplexMode.FDD:
68 # Array of EARFCNUL values that map to EARFCNDL
69 self.earfcnul = range(
70 start_earfcnul,
71 start_earfcnul + len(earfcndl),
72 )
73 # Array of UL frequencies in MHz, one per EARFCNUL
74 self.freq_mhz_ul = [
75 start_freq_ul_mhz + 0.1 * (
76 earfcn -
77 self.earfcnul[0]
78 ) for earfcn in self.earfcnul
79 ]
80 else:
81 self.earfcnul = None
82 self.freq_mhz_ul = None
83
84
85# See, for example, http://niviuk.free.fr/lte_band.php for LTE band info
86LTE_BAND_INFO = {
87 # FDD bands
88 # duplex_mode, EARFCNDL, start_freq_dl, start_EARCNUL, start_freq_ul
89 1: LTEBandInfo(DuplexMode.FDD, range(0, 600), 2110, 18000, 1920),
90 2: LTEBandInfo(DuplexMode.FDD, range(600, 1200), 1930, 18600, 1850),
91 3: LTEBandInfo(DuplexMode.FDD, range(1200, 1950), 1805, 19200, 1710),
92 4: LTEBandInfo(DuplexMode.FDD, range(1950, 2400), 2110, 19950, 1710),
93 5: LTEBandInfo(DuplexMode.FDD, range(2400, 2649), 869, 20400, 824),
94 28: LTEBandInfo(DuplexMode.FDD, range(9210, 9660), 758, 27210, 703),
95 # TDD bands
96 # duplex_mode, EARFCNDL, start_freq_dl
97 33: LTEBandInfo(DuplexMode.TDD, range(36000, 36199), 1900),
98 34: LTEBandInfo(DuplexMode.TDD, range(36200, 36349), 2010),
99 35: LTEBandInfo(DuplexMode.TDD, range(36350, 36949), 1850),
100 36: LTEBandInfo(DuplexMode.TDD, range(36950, 37549), 1930),
101 37: LTEBandInfo(DuplexMode.TDD, range(37550, 37750), 1910),
102 38: LTEBandInfo(DuplexMode.TDD, range(37750, 38250), 2570),
103 39: LTEBandInfo(DuplexMode.TDD, range(38250, 38650), 1880),
104 40: LTEBandInfo(DuplexMode.TDD, range(38650, 39650), 2300),
105 41: LTEBandInfo(DuplexMode.TDD, range(39650, 41590), 2496),
106 42: LTEBandInfo(DuplexMode.TDD, range(41590, 43590), 3400),
107 43: LTEBandInfo(DuplexMode.TDD, range(43590, 45590), 3600),
108 44: LTEBandInfo(DuplexMode.TDD, range(45590, 46589), 703),
109 45: LTEBandInfo(DuplexMode.TDD, range(46590, 46789), 1447),
110 46: LTEBandInfo(DuplexMode.TDD, range(46790, 54539), 5150),
111 47: LTEBandInfo(DuplexMode.TDD, range(54540, 55239), 5855),
112 48: LTEBandInfo(DuplexMode.TDD, range(55240, 56740), 3550),
113 49: LTEBandInfo(DuplexMode.TDD, range(56740, 58239), 3550),
114 50: LTEBandInfo(DuplexMode.TDD, range(58240, 59089), 1432),
115 51: LTEBandInfo(DuplexMode.TDD, range(59090, 59139), 1427),
116 52: LTEBandInfo(DuplexMode.TDD, range(59140, 60139), 3300),
117 # For the band #53 start_freq_dl is float value which require some changes
118 # in the code
119 # 53: LTEBandInfo(DuplexMode.TDD, range(60140, 60254), 2483.5),
120
121}
122# TODO - add remaining FDD LTE bands
123
124
125def map_earfcndl_to_duplex_mode(earfcndl: int) -> Optional[DuplexMode]:
126 """
127 Returns None if we do not support the EARFCNDL
128 """
129 for band in LTE_BAND_INFO.keys():
130 if earfcndl in LTE_BAND_INFO[band].earfcndl:
131 return LTE_BAND_INFO[band].duplex_mode
132 return None
133
134
135def map_earfcndl_to_band_earfcnul_mode(earfcndl):
136 """ Inputs:
137 - EARFCNDL (integer)
138 Outputs:
139 - Band (integer)
140 - Mode (DuplexMode)
141 - EARFCNUL (integer - or None if TDD)
142 """
143 for band in LTE_BAND_INFO.keys():
144 if earfcndl in LTE_BAND_INFO[band].earfcndl:
145 if LTE_BAND_INFO[band].duplex_mode == DuplexMode.FDD:
146 index = LTE_BAND_INFO[band].earfcndl.index(earfcndl)
147 earfcnul = LTE_BAND_INFO[band].earfcnul[index]
148 else:
149 earfcnul = None
150
151 return band, LTE_BAND_INFO[band].duplex_mode, earfcnul
152
153 raise ValueError('EARFCNDL %d not found in LTE band info' % earfcndl)