e365cc4372222789d0221c827b3edacf17da5c4b
[o-du/phy.git] / fhi_lib / app / src / common.c
1 /******************************************************************************
2 *
3 *   Copyright (c) 2020 Intel.
4 *
5 *   Licensed under the Apache License, Version 2.0 (the "License");
6 *   you may not use this file except in compliance with the License.
7 *   You may obtain a copy of the License at
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *   Unless required by applicable law or agreed to in writing, software
12 *   distributed under the License is distributed on an "AS IS" BASIS,
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *   See the License for the specific language governing permissions and
15 *   limitations under the License.
16 *
17 *******************************************************************************/
18
19 #include <assert.h>
20 #include <err.h>
21 #include <arpa/inet.h>
22 #include <sys/time.h>
23 #include <time.h>
24
25 #include "common.h"
26 #include "xran_fh_o_du.h"
27 #include "xran_pkt.h"
28 #include "xran_pkt_up.h"
29 #include "xran_cp_api.h"
30 #include "xran_up_api.h"
31
32 #include "xran_mlog_lnx.h"
33
34 extern enum app_state state;
35
36 int iq_playback_buffer_size_dl = IQ_PLAYBACK_BUFFER_BYTES;
37 int iq_playback_buffer_size_ul = IQ_PLAYBACK_BUFFER_BYTES;
38
39 int iq_bfw_buffer_size_dl = IQ_PLAYBACK_BUFFER_BYTES;
40 int iq_bfw_buffer_size_ul = IQ_PLAYBACK_BUFFER_BYTES;
41
42 int iq_srs_buffer_size_ul = IQ_PLAYBACK_BUFFER_BYTES;
43
44 uint8_t numCCPorts = 1;
45 /* Number of antennas supported by front-end */
46
47 uint8_t num_eAxc = 4;
48 /* Number of CPRI ports supported by front-end */
49
50 int16_t *p_tx_play_buffer[MAX_ANT_CARRIER_SUPPORTED];
51 int32_t tx_play_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
52 int32_t tx_play_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
53
54 int16_t *p_tx_prach_play_buffer[MAX_ANT_CARRIER_SUPPORTED];
55 int32_t tx_prach_play_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
56 int32_t tx_prach_play_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
57
58 int16_t *p_tx_srs_play_buffer[XRAN_MAX_SECTOR_NR*XRAN_MAX_ANT_ARRAY_ELM_NR];
59 int32_t tx_srs_play_buffer_size[XRAN_MAX_SECTOR_NR*XRAN_MAX_ANT_ARRAY_ELM_NR];
60 int32_t tx_srs_play_buffer_position[XRAN_MAX_SECTOR_NR*XRAN_MAX_ANT_ARRAY_ELM_NR];
61
62 int16_t *p_rx_log_buffer[MAX_ANT_CARRIER_SUPPORTED];
63 int32_t rx_log_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
64 int32_t rx_log_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
65
66 int16_t *p_prach_log_buffer[MAX_ANT_CARRIER_SUPPORTED];
67 int32_t prach_log_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
68 int32_t prach_log_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
69
70 int16_t *p_srs_log_buffer[XRAN_MAX_SECTOR_NR*XRAN_MAX_ANT_ARRAY_ELM_NR];
71 int32_t srs_log_buffer_size[XRAN_MAX_SECTOR_NR*XRAN_MAX_ANT_ARRAY_ELM_NR];
72 int32_t srs_log_buffer_position[XRAN_MAX_SECTOR_NR*XRAN_MAX_ANT_ARRAY_ELM_NR];
73
74 int16_t *p_tx_buffer[MAX_ANT_CARRIER_SUPPORTED];
75 int32_t tx_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
76
77 int16_t *p_rx_buffer[MAX_ANT_CARRIER_SUPPORTED];
78 int32_t rx_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
79
80 /* beamforming weights for UL (O-DU) */
81 int16_t *p_tx_dl_bfw_buffer[MAX_ANT_CARRIER_SUPPORTED];
82 int32_t tx_dl_bfw_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
83 int32_t tx_dl_bfw_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
84
85 /* beamforming weights for UL (O-DU) */
86 int16_t *p_tx_ul_bfw_buffer[MAX_ANT_CARRIER_SUPPORTED];
87 int32_t tx_ul_bfw_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
88 int32_t tx_ul_bfw_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
89
90 /* beamforming weights for UL (O-RU) */
91 int16_t *p_rx_dl_bfw_buffer[MAX_ANT_CARRIER_SUPPORTED];
92 int32_t rx_dl_bfw_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
93 int32_t rx_dl_bfw_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
94
95 /* beamforming weights for UL (O-RU) */
96 int16_t *p_rx_ul_bfw_buffer[MAX_ANT_CARRIER_SUPPORTED];
97 int32_t rx_ul_bfw_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
98 int32_t rx_ul_bfw_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
99
100 // F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
101 uint16_t nLteNumRbsPerSymF1[1][4] =
102 {
103     //  5MHz    10MHz   15MHz   20 MHz
104         {25,    50,     75,     100},         // Numerology 0 (15KHz)
105 };
106
107 // F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
108 uint16_t nNumRbsPerSymF1[3][13] =
109 {
110     //  5MHz    10MHz   15MHz   20 MHz  25 MHz  30 MHz  40 MHz  50MHz   60 MHz  70 MHz  80 MHz   90 MHz  100 MHz
111         {25,    52,     79,     106,    133,    160,    216,    270,    0,         0,      0,      0,      0},         // Numerology 0 (15KHz)
112         {11,    24,     38,     51,     65,     78,     106,    133,    162,       0,    217,    245,    273},         // Numerology 1 (30KHz)
113         {0,     11,     18,     24,     31,     38,     51,     65,     79,        0,    107,    121,    135}          // Numerology 2 (60KHz)
114 };
115
116 // F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
117 uint16_t nNumRbsPerSymF2[2][4] =
118 {
119     //  50Mhz  100MHz  200MHz   400MHz
120         {66,    132,    264,     0},        // Numerology 2 (60KHz)
121         {32,    66,     132,     264}       // Numerology 3 (120KHz)
122 };
123
124 // 38.211 - Table 4.2.1
125 uint16_t nSubCarrierSpacing[5] =
126 {
127     15,     // mu = 0
128     30,     // mu = 1
129     60,     // mu = 2
130     120,    // mu = 3
131     240     // mu = 4
132 };
133
134 // TTI interval in us (slot duration)
135 uint16_t nTtiInterval[4] =
136 {
137     1000,     // mu = 0
138     500,     // mu = 1
139     250,     // mu = 2
140     125,     // mu = 3
141 };
142
143
144 // F1 Tables 38.101-1 Table F.5.3. Window length for normal CP
145 uint16_t nCpSizeF1[3][13][2] =
146 {
147     //    5MHz      10MHz      15MHz       20 MHz      25 MHz     30 MHz      40 MHz       50MHz       60 MHz      70 MHz     80 MHz     90 MHz     100 MHz
148         {{40, 36}, {80, 72}, {120, 108}, {160, 144}, {160, 144}, {240, 216}, {320, 288}, {320, 288},     {0, 0},     {0, 0},     {0, 0},     {0, 0},     {0, 0}},        // Numerology 0 (15KHz)
149         {{22, 18}, {44, 36},   {66, 54},   {88, 72},   {88, 72}, {132, 108}, {176, 144}, {176, 144}, {264, 216}, {264, 216}, {352, 288}, {352, 288}, {352, 288}},       // Numerology 1 (30KHz)
150         {  {0, 0}, {26, 18},   {39, 27},   {52, 36},   {52, 36},   {78, 54},  {104, 72},  {104, 72}, {156, 108}, {156, 108}, {208, 144}, {208, 144}, {208, 144}},       // Numerology 2 (60KHz)
151 };
152
153 // F2 Tables 38.101-2 Table F.5.3. Window length for normal CP
154 int16_t nCpSizeF2[2][4][2] =
155 {
156     //    50Mhz    100MHz      200MHz     400MHz
157         {  {0, 0}, {104, 72}, {208, 144}, {416, 288}}, // Numerology 2 (60KHz)
158         {{68, 36}, {136, 72}, {272, 144}, {544, 288}}, // Numerology 3 (120KHz)
159 };
160
161 uint32_t gMaxSlotNum;
162 uint32_t gNumDLCtx;
163 uint32_t gNumULCtx;
164 uint32_t gDLResetAdvance;
165 uint32_t gDLProcAdvance;
166 uint32_t gULProcAdvance;
167
168 static uint16_t g_NumSlotTDDLoop[XRAN_MAX_SECTOR_NR] = { XRAN_NUM_OF_SLOT_IN_TDD_LOOP };
169 static uint16_t g_NumDLSymSp[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {0};
170 static uint16_t g_NumULSymSp[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {0};
171 static uint8_t g_SlotType[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {{XRAN_SLOT_TYPE_INVALID}};
172 float g_UlRate[XRAN_MAX_SECTOR_NR] = {0.0};
173 float g_DlRate[XRAN_MAX_SECTOR_NR] = {0.0};
174
175 uint32_t app_xran_get_tti_interval(uint8_t nMu)
176 {
177     if (nMu < 4)
178     {
179         return nTtiInterval[nMu];
180     }
181     else
182     {
183         printf("ERROR: %s Mu[%d] is not valid\n",__FUNCTION__, nMu);
184     }
185
186     return 0;
187 }
188
189 uint32_t app_xran_get_scs(uint8_t nMu)
190 {
191     if (nMu <= 3)
192     {
193         return nSubCarrierSpacing[nMu];
194     }
195     else
196     {
197         printf("ERROR: %s Mu[%d] is not valid\n",__FUNCTION__, nMu);
198     }
199
200     return 0;
201 }
202
203
204
205
206 //-------------------------------------------------------------------------------------------
207 /** @ingroup group_nr5g_source_phy_common
208  *
209  *  @param[in]   nNumerology - Numerology determine sub carrier spacing, Value: 0->4 0: 15khz,  1: 30khz,  2: 60khz 3: 120khz, 4: 240khz
210  *  @param[in]   nBandwidth - Carrier bandwidth for in MHz. Value: 5->400
211  *  @param[in]   nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
212  *
213  *  @return  Number of RBs in cell
214  *
215  *  @description
216  *  Returns number of RBs based on 38.101-1 and 38.101-2 for the cell
217  *
218 **/
219 //-------------------------------------------------------------------------------------------
220 uint16_t app_xran_get_num_rbs(uint8_t ranTech, uint32_t nNumerology, uint32_t nBandwidth, uint32_t nAbsFrePointA)
221 {
222     uint32_t error = 1;
223     uint16_t numRBs = 0;
224
225     if (ranTech == XRAN_RAN_LTE) {
226         switch(nBandwidth)
227         {
228             case PHY_BW_5_0_MHZ:
229                 numRBs = nLteNumRbsPerSymF1[nNumerology][0];
230                 error = 0;
231             break;
232             case PHY_BW_10_0_MHZ:
233                 numRBs = nLteNumRbsPerSymF1[nNumerology][1];
234                 error = 0;
235             break;
236             case PHY_BW_15_0_MHZ:
237                 numRBs = nLteNumRbsPerSymF1[nNumerology][2];
238                 error = 0;
239             break;
240             case PHY_BW_20_0_MHZ:
241                 numRBs = nLteNumRbsPerSymF1[nNumerology][3];
242                 error = 0;
243             break;
244             default:
245                 error = 1;
246             break;
247         }
248     } else if (nAbsFrePointA <= 6000000) {
249         // F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
250         if (nNumerology < 3)
251         {
252             switch(nBandwidth)
253             {
254                 case PHY_BW_5_0_MHZ:
255                     numRBs = nNumRbsPerSymF1[nNumerology][0];
256                     error = 0;
257                 break;
258                 case PHY_BW_10_0_MHZ:
259                     numRBs = nNumRbsPerSymF1[nNumerology][1];
260                     error = 0;
261                 break;
262                 case PHY_BW_15_0_MHZ:
263                     numRBs = nNumRbsPerSymF1[nNumerology][2];
264                     error = 0;
265                 break;
266                 case PHY_BW_20_0_MHZ:
267                     numRBs = nNumRbsPerSymF1[nNumerology][3];
268                     error = 0;
269                 break;
270                 case PHY_BW_25_0_MHZ:
271                     numRBs = nNumRbsPerSymF1[nNumerology][4];
272                     error = 0;
273                 break;
274                 case PHY_BW_30_0_MHZ:
275                     numRBs = nNumRbsPerSymF1[nNumerology][5];
276                     error = 0;
277                 break;
278                 case PHY_BW_40_0_MHZ:
279                     numRBs = nNumRbsPerSymF1[nNumerology][6];
280                     error = 0;
281                 break;
282                 case PHY_BW_50_0_MHZ:
283                     numRBs = nNumRbsPerSymF1[nNumerology][7];
284                     error = 0;
285                 break;
286                 case PHY_BW_60_0_MHZ:
287                     numRBs = nNumRbsPerSymF1[nNumerology][8];
288                     error = 0;
289                 break;
290                 case PHY_BW_70_0_MHZ:
291                     numRBs = nNumRbsPerSymF1[nNumerology][9];
292                     error = 0;
293                 break;
294                 case PHY_BW_80_0_MHZ:
295                     numRBs = nNumRbsPerSymF1[nNumerology][10];
296                     error = 0;
297                 break;
298                 case PHY_BW_90_0_MHZ:
299                     numRBs = nNumRbsPerSymF1[nNumerology][11];
300                     error = 0;
301                 break;
302                 case PHY_BW_100_0_MHZ:
303                     numRBs = nNumRbsPerSymF1[nNumerology][12];
304                     error = 0;
305                 break;
306                 default:
307                     error = 1;
308                 break;
309             }
310         }
311     }
312     else
313     {
314         if ((nNumerology >= 2) && (nNumerology <= 3))
315         {
316             // F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
317             switch(nBandwidth)
318             {
319                 case PHY_BW_50_0_MHZ:
320                     numRBs = nNumRbsPerSymF2[nNumerology-2][0];
321                     error = 0;
322                 break;
323                 case PHY_BW_100_0_MHZ:
324                     numRBs = nNumRbsPerSymF2[nNumerology-2][1];
325                     error = 0;
326                 break;
327                 case PHY_BW_200_0_MHZ:
328                     numRBs = nNumRbsPerSymF2[nNumerology-2][2];
329                     error = 0;
330                 break;
331                 case PHY_BW_400_0_MHZ:
332                     numRBs = nNumRbsPerSymF2[nNumerology-2][3];
333                     error = 0;
334                 break;
335                 default:
336                     error = 1;
337                 break;
338             }
339         }
340     }
341
342
343     if (error)
344     {
345         printf("ERROR: %s: RAN[%s] nNumerology[%d] nBandwidth[%d] nAbsFrePointA[%d]\n",__FUNCTION__, (ranTech ? "LTE" : "5G NR"), nNumerology, nBandwidth, nAbsFrePointA);
346     }
347     else
348     {
349         printf("%s: RAN [%s] nNumerology[%d] nBandwidth[%d] nAbsFrePointA[%d] numRBs[%d]\n",__FUNCTION__, (ranTech ? "LTE" : "5G NR"), nNumerology, nBandwidth, nAbsFrePointA, numRBs);
350     }
351
352     return numRBs;
353 }
354
355 //-------------------------------------------------------------------------------------------
356 /** @ingroup phy_cal_nrarfcn
357  *
358  *  @param[in]   center frequency
359  *
360  *  @return  NR-ARFCN
361  *
362  *  @description
363  *  This calculates NR-ARFCN value according to center frequency
364  *
365 **/
366 //-------------------------------------------------------------------------------------------
367 uint32_t app_xran_cal_nrarfcn(uint32_t nCenterFreq)
368 {
369     uint32_t nDeltaFglobal,nFoffs,nNoffs;
370     uint32_t nNRARFCN = 0;
371
372     if(nCenterFreq > 0 && nCenterFreq < 3000*1000)
373     {
374         nDeltaFglobal = 5;
375         nFoffs = 0;
376         nNoffs = 0;
377     }
378     else if(nCenterFreq >= 3000*1000 && nCenterFreq < 24250*1000)
379     {
380         nDeltaFglobal = 15;
381         nFoffs = 3000*1000;
382         nNoffs = 600000;
383     }
384     else if(nCenterFreq >= 24250*1000 && nCenterFreq <= 100000*1000)
385     {
386         nDeltaFglobal = 60;
387         nFoffs = 24250080;
388         nNoffs = 2016667;
389     }
390     else
391     {
392          printf("@@@@ incorrect center frerquency %d\n",nCenterFreq);
393          return (0);
394     }
395
396     nNRARFCN = ((nCenterFreq - nFoffs)/nDeltaFglobal) + nNoffs;
397
398     printf("%s: nCenterFreq[%d] nDeltaFglobal[%d] nFoffs[%d] nNoffs[%d] nNRARFCN[%d]\n", __FUNCTION__, nCenterFreq, nDeltaFglobal, nFoffs, nNoffs, nNRARFCN);
399     return (nNRARFCN);
400 }
401
402 int32_t app_xran_slot_limit(int32_t nSfIdx)
403 {
404     while (nSfIdx < 0) {
405         nSfIdx += gMaxSlotNum;
406     }
407
408     while (nSfIdx >= gMaxSlotNum) {
409         nSfIdx -= gMaxSlotNum;
410     }
411
412     return nSfIdx;
413 }
414
415 void app_xran_clear_slot_type(uint32_t nPhyInstanceId)
416 {
417     g_UlRate[nPhyInstanceId] = 0.0;
418     g_DlRate[nPhyInstanceId] = 0.0;
419     g_NumSlotTDDLoop[nPhyInstanceId] = 1;
420 }
421
422 int32_t app_xran_set_slot_type(uint32_t nPhyInstanceId, uint32_t nFrameDuplexType, uint32_t nTddPeriod, struct xran_slot_config *psSlotConfig)
423 {
424     uint32_t nSlotNum, nSymNum, nVal, i;
425     uint32_t numDlSym, numUlSym, numGuardSym;
426     uint32_t numDlSlots = 0, numUlSlots = 0, numSpDlSlots = 0, numSpUlSlots = 0, numSpSlots = 0;
427     char sSlotPattern[XRAN_SLOT_TYPE_LAST][10] = {"IN\0", "DL\0", "UL\0", "SP\0", "FD\0"};
428
429     // nPhyInstanceId    Carrier ID
430     // nFrameDuplexType  0 = FDD 1 = TDD
431     // nTddPeriod        Tdd Periodicity
432     // psSlotConfig[80]  Slot Config Structure for nTddPeriod Slots
433
434     g_UlRate[nPhyInstanceId] = 0.0;
435     g_DlRate[nPhyInstanceId] = 0.0;
436     g_NumSlotTDDLoop[nPhyInstanceId] = nTddPeriod;
437
438     for (i = 0; i < XRAN_NUM_OF_SLOT_IN_TDD_LOOP; i++)
439     {
440         g_SlotType[nPhyInstanceId][i] = XRAN_SLOT_TYPE_INVALID;
441         g_NumDLSymSp[nPhyInstanceId][i] = 0;
442         g_NumULSymSp[nPhyInstanceId][i] = 0;
443     }
444
445     if (nFrameDuplexType == XRAN_FDD)
446     {
447         for (i = 0; i < XRAN_NUM_OF_SLOT_IN_TDD_LOOP; i++)
448         {
449             g_SlotType[nPhyInstanceId][i] = XRAN_SLOT_TYPE_FDD;
450         }
451         g_NumSlotTDDLoop[nPhyInstanceId] = 1;
452         g_DlRate[nPhyInstanceId] = 1.0;
453         g_UlRate[nPhyInstanceId] = 1.0;
454     }
455     else
456     {
457         for (nSlotNum = 0; nSlotNum < nTddPeriod; nSlotNum++)
458         {
459             numDlSym = 0;
460             numUlSym = 0;
461             numGuardSym = 0;
462             for (nSymNum = 0; nSymNum < XRAN_NUM_OF_SYMBOL_PER_SLOT; nSymNum++)
463             {
464                 switch(psSlotConfig[nSlotNum].nSymbolType[nSymNum])
465                 {
466                     case XRAN_SYMBOL_TYPE_DL:
467                         numDlSym++;
468                     break;
469                     case XRAN_SYMBOL_TYPE_GUARD:
470                         numGuardSym++;
471                     break;
472                     default:
473                         numUlSym++;
474                     break;
475                 }
476             }
477
478             // printf("nSlotNum[%d] : numDlSym[%d] numGuardSym[%d] numUlSym[%d]\n", nSlotNum, numDlSym, numGuardSym, numUlSym);
479
480             if ((numUlSym == 0) && (numGuardSym == 0))
481             {
482                 g_SlotType[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_DL;
483                 numDlSlots++;
484             }
485             else if ((numDlSym == 0) && (numGuardSym == 0))
486             {
487                 g_SlotType[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_UL;
488                 numUlSlots++;
489             }
490             else
491             {
492                 g_SlotType[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_SP;
493                 numSpSlots++;
494
495                 if (numDlSym)
496                 {
497                     numSpDlSlots++;
498                     g_NumDLSymSp[nPhyInstanceId][nSlotNum] = numDlSym;
499                 }
500                 if (numUlSym)
501                 {
502                     numSpUlSlots++;
503                     g_NumULSymSp[nPhyInstanceId][nSlotNum] = numUlSym;
504                 }
505             }
506
507             // printf("            numDlSlots[%d] numUlSlots[%d] numSpSlots[%d] numSpDlSlots[%d] numSpUlSlots[%d]\n", numDlSlots, numUlSlots, numSpSlots, numSpDlSlots, numSpUlSlots);
508         }
509
510         g_DlRate[nPhyInstanceId] = (float)(numDlSlots + numSpDlSlots) / (float)nTddPeriod;
511         g_UlRate[nPhyInstanceId] = (float)(numUlSlots + numSpUlSlots) / (float)nTddPeriod;
512     }
513
514     printf("set_slot_type: nPhyInstanceId[%d] nFrameDuplexType[%d], nTddPeriod[%d]\n",
515         nPhyInstanceId, nFrameDuplexType, nTddPeriod);
516
517     printf("DLRate[%f] ULRate[%f]\n", g_DlRate[nPhyInstanceId], g_UlRate[nPhyInstanceId]);
518
519     nVal = (g_NumSlotTDDLoop[nPhyInstanceId] < 10) ? g_NumSlotTDDLoop[nPhyInstanceId] : 10;
520
521     printf("SlotPattern:\n");
522     printf("Slot:   ");
523     for (nSlotNum = 0; nSlotNum < nVal; nSlotNum++)
524     {
525         printf("%d    ", nSlotNum);
526     }
527     printf("\n");
528
529     printf("  %3d   ", 0);
530     for (nSlotNum = 0, i = 0; nSlotNum < g_NumSlotTDDLoop[nPhyInstanceId]; nSlotNum++)
531     {
532         printf("%s   ", sSlotPattern[g_SlotType[nPhyInstanceId][nSlotNum]]);
533         i++;
534         if ((i == 10) && ((nSlotNum+1) < g_NumSlotTDDLoop[nPhyInstanceId]))
535         {
536             printf("\n");
537             printf("  %3d   ", nSlotNum);
538             i = 0;
539         }
540     }
541     printf("\n\n");
542
543     return 0;
544 }
545
546 int32_t app_xran_get_slot_type(int32_t nCellIdx, int32_t nSlotdx, int32_t nType)
547 {
548     int32_t nSfIdxMod, nSfType, ret = 0;
549
550     nSfIdxMod = app_xran_slot_limit(nSlotdx) % ((g_NumSlotTDDLoop[nCellIdx] > 0) ? g_NumSlotTDDLoop[nCellIdx]: 1);
551     nSfType = g_SlotType[nCellIdx][nSfIdxMod];
552
553     if (nSfType == nType)
554     {
555         ret = 1;
556     }
557     else if (nSfType == XRAN_SLOT_TYPE_SP)
558     {
559         if ((nType == XRAN_SLOT_TYPE_DL) && g_NumDLSymSp[nCellIdx][nSfIdxMod])
560         {
561             ret = 1;
562         }
563
564         if ((nType == XRAN_SLOT_TYPE_UL) && g_NumULSymSp[nCellIdx][nSfIdxMod])
565         {
566             ret = 1;
567         }
568     }
569     else if (nSfType == XRAN_SLOT_TYPE_FDD)
570     {
571         ret = 1;
572     }
573
574     return ret;
575 }
576
577
578
579 void sys_save_buf_to_file(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
580 {
581     if (size)
582     {
583         if (filename && bufname)
584         {
585             FILE           *file;
586             printf("Storing %s to file %s: ", bufname, filename);
587             file = fopen(filename, "wb");
588             if (file == NULL)
589             {
590                 printf("can't open file %s!!!", filename);
591             }
592             else
593             {
594                 uint32_t             num;
595                 num = fwrite(pBuffer, buffers_num, size, file);
596                 fflush(file);
597                 fclose(file);
598                 printf("from addr (0x%lx) size (%d) bytes num (%d)", (uint64_t)pBuffer, size, num);
599             }
600             printf(" \n");
601         }
602         else
603         {
604             printf(" the file name, buffer name are not set!!!");
605         }
606     }
607     else
608     {
609         printf(" the %s is free: size = %d bytes!!!", bufname, size);
610     }
611 }
612
613 int sys_load_file_to_buff(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
614 {
615     unsigned int  file_size = 0;
616     int  num= 0;
617
618     if (size)
619     {
620         if (filename && bufname)
621         {
622             FILE           *file;
623             printf("Loading file %s to  %s: ", filename, bufname);
624             file = fopen(filename, "rb");
625
626
627             if (file == NULL)
628             {
629                 printf("can't open file %s!!!", filename);
630                 exit(-1);
631             }
632             else
633             {
634                 fseek(file, 0, SEEK_END);
635                 file_size = ftell(file);
636                 fseek(file, 0, SEEK_SET);
637
638                 if ((file_size > size) || (file_size == 0))
639                     file_size = size;
640
641                 printf("Reading IQ samples from file: File Size: %d [Buffer Size: %d]\n", file_size, size);
642
643                 num = fread(pBuffer, buffers_num, size, file);
644                 fflush(file);
645                 fclose(file);
646                 printf("from addr (0x%lx) size (%d) bytes num (%d)", (uint64_t)pBuffer, file_size, num);
647             }
648             printf(" \n");
649
650         }
651         else
652         {
653             printf(" the file name, buffer name are not set!!!");
654         }
655     }
656     else
657     {
658         printf(" the %s is free: size = %d bytes!!!", bufname, size);
659     }
660     return num;
661 }
662
663
664 void sys_save_buf_to_file_txt(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
665 {
666     unsigned int i;
667     int ret = 0;
668     if (pBuffer == NULL)
669         return;
670
671     if (size)
672     {
673         if (filename && bufname)
674         {
675             FILE           *file;
676             printf("Storing %s to file %s: ", bufname, filename);
677             file = fopen(filename, "w");
678             if (file == NULL)
679             {
680                 printf("can't open file %s!!!", filename);
681                 exit(-1);
682             }
683             else
684             {
685                 uint32_t num = 0;
686
687                 signed short *ptr = (signed short*)pBuffer;
688                 for (i = 0; i < (size/((unsigned int)sizeof(signed short) /** 2 * 2 * 2*/)); i = i + 2)
689                 {
690 #ifndef CSCOPE_DEBUG
691                     ret = fprintf(file,"%d %d\n", ptr[i], ptr[i + 1]);
692 #else
693                     ret = fprintf(file,"%d %d ", ptr[i], ptr[i + 1]);
694                     /*      I data => Ramp data, from 1 to 792.
695                             Q data => Contains time information of the current symbol:
696                             Bits [15:14] = Antenna-ID
697                             Bits [13:12] = \9300\94
698                             Bits [11:8]  = Subframe-ID
699                             Bits [7:4]   = Slot-ID
700                             Bits [3:0]   = Symbol-ID */
701                             fprintf(file, "0x%04x: ant %d Subframe-ID %d Slot-ID %d Symbol-ID %d\n",
702                                         ptr[i + 1], (ptr[i + 1]>>14) & 0x3,  (ptr[i + 1]>>8) & 0xF,  (ptr[i + 1]>>4) & 0xF, (ptr[i + 1]>>0) & 0xF);
703 #endif
704                     if (ret < 0)
705                     {
706                         printf("fprintf %d\n", ret);
707                         fclose(file);
708                         break;
709                     }
710                     num++;
711                 }
712                 fflush(file);
713                 fclose(file);
714                 printf("from addr (0x%lx) size (%d) IQ num (%d)", (uint64_t)pBuffer, size, num);
715             }
716             printf(" \n");
717         }
718         else
719         {
720             printf(" the file name, buffer name are not set!!!");
721         }
722     }
723     else
724     {
725         printf(" the %s is free: size = %d bytes!!!", bufname, size);
726     }
727 }
728