comparison src/cs/layer1/p_cfile/l1p_ctl.c @ 302:0740b5ff15f6

reconstructed L1_GPRS source imported from tcs211-l1-reconst
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 31 Oct 2017 03:42:35 +0000
parents
children
comparison
equal deleted inserted replaced
301:a963c5c35f8d 302:0740b5ff15f6
1 /************* Revision Controle System Header *************
2 * GSM Layer 1 software
3 * L1P_CTL.C
4 *
5 * Filename l1p_ctl.c
6 * Copyright 2003 (C) Texas Instruments
7 *
8 ************* Revision Controle System Header *************/
9
10 #include "l1_macro.h"
11 #include "l1_confg.h"
12
13 #if L1_GPRS
14 #if (CODE_VERSION == SIMULATION)
15 #include <string.h>
16 #include "l1_types.h"
17 #include "sys_types.h"
18 #include "l1_const.h"
19 #include "l1_time.h"
20 #include "l1_signa.h"
21 #if TESTMODE
22 #include "l1tm_defty.h"
23 #endif
24 #if (AUDIO_TASK == 1)
25 #include "l1audio_const.h"
26 #include "l1audio_cust.h"
27 #include "l1audio_signa.h"
28 #include "l1audio_defty.h"
29 #include "l1audio_msgty.h"
30 #endif
31 #if (L1_GTT == 1)
32 #include "l1gtt_const.h"
33 #include "l1gtt_defty.h"
34 #endif
35 #if (L1_MP3 == 1)
36 #include "l1mp3_defty.h"
37 #endif
38 #if (L1_MIDI == 1)
39 #include "l1midi_defty.h"
40 #endif
41 #include "l1_defty.h"
42 #include "cust_os.h"
43 #include "l1_msgty.h"
44 #include "l1_varex.h"
45 #include "l1_proto.h"
46 #include "l1_mftab.h"
47 #include "l1_tabs.h"
48 #include "l1_ver.h"
49
50 #include "l1_ctl.h"
51
52 #include "l1p_cons.h"
53 #include "l1p_msgt.h"
54 #include "l1p_deft.h"
55 #include "l1p_vare.h"
56 #include "l1p_sign.h"
57 #if (OP_L1_STANDALONE == 1)
58 #ifdef _INLINE
59 #define INLINE static inline // Inline functions when -v option is set
60 #else // when the compiler is ivoked.
61 #define INLINE
62 #endif
63 #endif //0maps00090550
64 #else
65 #include <string.h>
66 #include "l1_types.h"
67 #include "sys_types.h"
68 #include "l1_const.h"
69 #include "l1_time.h"
70 #include "l1_signa.h"
71
72 #if (RF_FAM == 61)
73 #include "tpudrv61.h"
74 #endif
75
76 #if TESTMODE
77 #include "l1tm_defty.h"
78 #endif
79 #if (AUDIO_TASK == 1)
80 #include "l1audio_const.h"
81 #include "l1audio_cust.h"
82 #include "l1audio_defty.h"
83 #endif
84 #if (L1_GTT == 1)
85 #include "l1gtt_const.h"
86 #include "l1gtt_defty.h"
87 #endif
88 #if (L1_MP3 == 1)
89 #include "l1mp3_defty.h"
90 #endif
91 #if (L1_MIDI == 1)
92 #include "l1midi_defty.h"
93 #endif
94 #include "l1_defty.h"
95 #include "cust_os.h"
96 #include "l1_msgty.h"
97 #include "l1_varex.h"
98 #include "l1_proto.h"
99
100 #include "l1_ctl.h"
101
102 #include "l1p_cons.h"
103 #include "l1p_msgt.h"
104 #include "l1p_deft.h"
105 #include "l1p_vare.h"
106 #include "l1p_sign.h"
107 #if (OP_L1_STANDALONE == 1)
108 #ifdef _INLINE
109 #define INLINE static inline // Inline functions when -v option is set
110 #else // when the compiler is ivoked.
111 #define INLINE
112 #endif
113 #endif //omaps00090550
114 #endif
115
116 #if(RF_FAM == 61)
117 #include "l1_rf61.h"
118 #endif
119
120
121 // Macro definition
122 //-----------------
123 #define min(value1,value2) \
124 value1 < value2 ? value1 : value2
125
126 // External prototypes
127 //--------------------
128
129 WORD8 l1ctl_encode_delta1(UWORD16 radio_freq);
130
131 /*********************************************************/
132 /* GPRS AGC Algorithms */
133 /*********************************************************/
134
135 /*-------------------------------------------------------*/
136 /* l1pctl_pagc_ctrl() */
137 /*-------------------------------------------------------*/
138 /* Description: */
139 /* =========== */
140 /* Based on the same principle as the one used for PAGC */
141 /* algorithm except that we also feed the beacon FIFO */
142 /* with IL measured on other carriers (Pb parameter is */
143 /* applied) */
144 /* This function is used in the control phase of PCCCH, */
145 /* serving PBCCH and PTCCH reading tasks to determine */
146 /* which AGC and lna_off must apply */
147 /* */
148 /* WARNING: in the layer 1 code, input levels IL(l1) use */
149 /* format 7.1: */
150 /* ********************* */
151 /* * IL(l1) = - 2 x IL * */
152 /* ********************* */
153 /* -> Reversed sign, reversed test conditions */
154 /* -> max replaced by min */
155 /* ex: if IL -120 dBm, IL(l1) = 240 */
156 /*-------------------------------------------------------*/
157 void l1pctl_pagc_ctrl(WORD8 *agc, UWORD8 *lna_off, UWORD16 radio_freq, UWORD8 serving_cell)
158 {
159 UWORD8 pb;
160 WORD16 input_level, new_calibrated_IL;
161 WORD32 freq_index;
162 UWORD16 beacon_frequency;
163 UWORD8 *lna_off_ptr;
164 UWORD8 curve_id;
165
166 // We memorize the LNA state used for other serving frequencies that can be used
167 // in Packet idle mode
168 static UWORD8 lna_off_others = 0;
169
170 if (serving_cell == TRUE)
171 {
172 beacon_frequency = l1a_l1s_com.Scell_info.radio_freq;
173 pb = l1a_l1s_com.Scell_info.pb;
174 lna_off_ptr = &lna_off_others;
175 curve_id = MAX_ID;
176 }
177 else
178 {
179 beacon_frequency = l1pa_l1ps_com.pbcchn.bcch_carrier;
180 pb = l1pa_l1ps_com.pbcchn.pb;
181 lna_off_ptr = lna_off;
182 curve_id = AV_ID;
183 }
184
185 #if(L1_FF_MULTIBAND == 0)
186 freq_index = beacon_frequency - l1_config.std.radio_freq_index_offset;
187 #else
188 freq_index = l1_multiband_radio_freq_convert_into_operative_radio_freq(beacon_frequency);
189 #endif
190
191
192 // If the downlink channel is decoded on the beacon frequency
193 if (radio_freq == beacon_frequency)
194 {
195 // Downlink task on the serving beacon: process AGC according to the "beacon IL"
196 input_level = l1a_l1s_com.last_input_level[freq_index].input_level;
197
198 // lna_off already processed in the read phase
199 *lna_off = l1a_l1s_com.last_input_level[freq_index].lna_off;
200 }
201
202 // If the downlink channel is decoded on a frequency other than the beacon
203 else
204 {
205
206 // Process AGC according to "beacon IL + Pb"
207 input_level = (WORD16) (l1a_l1s_com.last_input_level[freq_index].input_level + pb);
208
209 // IL_2_AGC_xx array size
210 if (input_level>INDEX_MAX)
211 input_level = INDEX_MAX;
212
213 // lna_off must be processed in the control phase because input_level
214 // depends on last_input_level and Pb, and last_input_level or pb can have changed
215 // at any time
216
217 // New calibrated IL to reach on radio freq other than beacon
218 new_calibrated_IL = (WORD16) (input_level - l1ctl_encode_delta1(radio_freq)
219 - l1ctl_encode_delta2(radio_freq));
220
221 // IL_2_AGC_xx array size
222 if (new_calibrated_IL>INDEX_MAX)
223 new_calibrated_IL = INDEX_MAX;
224
225 // lna_off computing...
226 l1ctl_encode_lna((UWORD8)(new_calibrated_IL>>1),
227 lna_off_ptr,
228 radio_freq);
229
230 *lna_off = *lna_off_ptr;
231 } // End if "radio_freq != beacon_frequency"
232
233 // Process AGC to apply
234 *agc = Cust_get_agc_from_IL(radio_freq,
235 input_level >> 1,
236 curve_id);
237
238 // Store lna_off and input_level field used for current CTRL in order to be able
239 // to build IL from pm in READ phase.
240 l1a_l1s_com.Scell_used_IL.input_level = (UWORD8)input_level;
241 l1a_l1s_com.Scell_used_IL.lna_off = *lna_off;
242
243 } // End of "l1pctl_pagc_ctrl"
244
245 /*-------------------------------------------------------*/
246 /* l1pctl_pagc_read() */
247 /*-------------------------------------------------------*/
248 /* Description : */
249 /* =========== */
250 /* Based on the same principle as the one used for PAGC */
251 /* algorithm except that we also feed the beacon FIFO */
252 /* with IL measured on other carriers (Pb parameter is */
253 /* applied) */
254 /* This function is used in the read phase of PCCCH and */
255 /* serving PBCCH reading tasks to determine the IL value */
256 /* store it in the FIFO and find the next IL to use */
257 /* */
258 /* WARNING: in the layer 1 code, input levels IL(l1) use */
259 /* format 7.1: */
260 /* ********************* */
261 /* * IL(l1) = - 2 x IL * */
262 /* ********************* */
263 /* -> Reversed sign, reversed test conditions */
264 /* -> max replaced by min */
265 /* ex: if IL -120 dBm, IL(l1) = 240 */
266 /*-------------------------------------------------------*/
267 UWORD8 l1pctl_pagc_read(UWORD8 pm, UWORD16 radio_freq)
268 {
269 UWORD8 i, new_IL;
270 WORD8 delta1_freq, delta2_freq;
271 WORD16 delta_drp_gain=0;
272 UWORD16 lna_value;
273 WORD16 used_agc, current_IL, new_calibrated_IL, current_calibrated_IL;
274 WORD32 serving_index;
275 #if (RF_FAM == 61)
276 UWORD16 arfcn;
277 #endif
278 UWORD8 lna_off;
279 UWORD16 dco_algo_ctl_pw_temp = 0;
280 UWORD8 if_ctl = 0;
281 #if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
282 UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GPRS;
283 #endif
284
285 #if (L1_FF_MULTIBAND == 0)
286 serving_index = l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset;
287
288 #else
289 serving_index = l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.Scell_info.radio_freq);
290 #endif /*if (L1_FF_MULTIBAND == 0)*/
291
292
293 // Calibration factors
294 delta1_freq = l1ctl_encode_delta1(radio_freq);
295 delta2_freq = l1ctl_encode_delta2(radio_freq);
296
297 // AGC used in the control phase (format F7.1)
298 used_agc = (Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.Scell_used_IL_dd.input_level >> 1, MAX_ID)) << 1;
299
300 // LNA attenuation
301 lna_value = l1a_l1s_com.Scell_used_IL_dd.lna_off * l1ctl_get_lna_att(radio_freq);
302
303 #if (RF_FAM == 61)
304 // DRP correction
305 #if (L1_FF_MULTIBAND == 0)
306 arfcn = Convert_l1_radio_freq(radio_freq);
307 #else
308 arfcn=radio_freq;
309 #endif
310
311 #if (CODE_VERSION != SIMULATION)
312
313 cust_get_if_dco_ctl_algo(&dco_algo_ctl_pw_temp, &if_ctl, (UWORD8) L1_IL_VALID ,
314 l1a_l1s_com.Scell_used_IL_dd.input_level,
315 radio_freq,if_threshold);
316 lna_off = l1a_l1s_com.Scell_used_IL_dd.lna_off;
317 delta_drp_gain = drp_gain_correction(arfcn, lna_off, used_agc); // F7.1 format
318 if(if_ctl == IF_100KHZ_DSP){
319 delta_drp_gain += SCF_ATTENUATION_LIF_100KHZ;
320 }
321 else{ /* i.e. if_ctl = IF_120KHZ_DSP*/
322 delta_drp_gain += SCF_ATTENUATION_LIF_120KHZ;
323 }
324
325 #endif
326 #endif
327
328 // current_IL processing
329
330 if (0==pm) // Check and filter illegal pm value by using last valid IL
331 {
332 current_IL = l1a_l1s_com.last_input_level[serving_index].input_level - lna_value;
333 }
334 else
335 {
336 current_IL = -(pm - (used_agc - delta_drp_gain) + lna_value - l1ctl_get_g_magic(radio_freq));
337
338 // IL normalization to beacon (ILnorm = IL - Pb)
339 if (radio_freq != l1a_l1s_com.Scell_info.radio_freq)
340 current_IL -= l1a_l1s_com.Scell_info.pb;
341 }
342
343 // Calibrated IL processing
344 // NOTE: calibrated_IL is normalized to beacon. This is needed for the
345 // pccch_lev processing
346 current_calibrated_IL = (WORD16) (current_IL - delta1_freq - delta2_freq);
347
348 // Protect IL stores against overflow
349 if (current_calibrated_IL>INDEX_MAX)
350 current_calibrated_IL=INDEX_MAX;
351 if (current_IL>INDEX_MAX)
352 current_IL=INDEX_MAX;
353
354 // FIFO management
355 for (i=3;i>0;i--)
356 l1a_l1s_com.Scell_info.buff_beacon[i] = l1a_l1s_com.Scell_info.buff_beacon[i-1];
357 l1a_l1s_com.Scell_info.buff_beacon[0] = (UWORD8)current_IL;
358
359 // Find min IL in FIFO
360 new_IL = l1ctl_find_max(l1a_l1s_com.Scell_info.buff_beacon, 4);
361
362 // Input levels are always stored with lna_on
363 new_calibrated_IL = (WORD16) (new_IL - delta1_freq - delta2_freq);
364
365 if (new_calibrated_IL>INDEX_MAX) new_calibrated_IL = INDEX_MAX;
366
367 l1ctl_encode_lna( (UWORD8)(new_calibrated_IL>>1),
368 &(l1a_l1s_com.last_input_level[serving_index].lna_off),
369 radio_freq );
370
371 l1a_l1s_com.last_input_level[serving_index].input_level = new_IL +
372 l1a_l1s_com.last_input_level[serving_index].lna_off * l1ctl_get_lna_att(radio_freq);
373
374 return((UWORD8)current_calibrated_IL);
375 } // End of "l1pctl_pagc_read"
376
377 /*-------------------------------------------------------*/
378 /* l1pctl_transfer_agc_init() */
379 /*-------------------------------------------------------*/
380 /* Description : */
381 /* =========== */
382 /* Packet transfer AGC algorithm initialization */
383 /*-------------------------------------------------------*/
384 void l1pctl_transfer_agc_init()
385 {
386 WORD16 calibrated_IL;
387 UWORD16 radio_freq;
388 WORD32 serving_index;
389 WORD16 input_level;
390
391 #if (L1_FF_MULTIBAND ==0)
392 serving_index = l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset;
393
394 #else
395 serving_index = l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.Scell_info.radio_freq);
396 #endif /*if L1_FF_MULTIBAND*/
397
398
399 // Daughter frequencies input level initialization
400 //------------------------------------------------
401 if (l1pa_l1ps_com.transfer.aset->dl_pwr_ctl.p0 == 255)
402 {
403 // No power control mode AGC algorithm
404 input_level = (WORD16) (l1a_l1s_com.last_input_level[serving_index].input_level + l1a_l1s_com.Scell_info.pb);
405
406 // Set fn_select to current_fn
407 l1ps.fn_select = l1s.actual_time.fn;
408 // Initialize algorithm in "SEARCH" phase
409 l1ps.phase = SEARCH;
410 }
411 else
412 {
413 // Downlink power control AGC algorithms
414 if (l1pa_l1ps_com.transfer.aset->dl_pwr_ctl.bts_pwr_ctl_mode == 0)
415 {
416 // BTS Power control mode A
417 input_level = (WORD16) (l1a_l1s_com.last_input_level[serving_index].input_level +
418 l1pa_l1ps_com.transfer.aset->dl_pwr_ctl.p0 + 10);
419
420 }
421 else
422 {
423 // BTS power control mode B
424 input_level = (WORD16) (l1a_l1s_com.last_input_level[serving_index].input_level +
425 l1pa_l1ps_com.transfer.aset->dl_pwr_ctl.p0);
426
427 // Initialization: PR = P0
428 l1ps.last_PR_good = l1pa_l1ps_com.transfer.aset->dl_pwr_ctl.p0;
429 }
430 }
431
432 if (input_level>INDEX_MAX) input_level = INDEX_MAX;
433 l1a_l1s_com.Scell_info.transfer_meas.input_level = (UWORD8)input_level;
434
435
436 // Daughter frequencies lna_off processing
437 //----------------------------------------
438
439 // We need to know on which frequency band we work
440 if (!l1pa_l1ps_com.transfer.aset->freq_param.chan_sel.h)
441 {
442 // Single frequency
443 radio_freq = l1pa_l1ps_com.transfer.aset->freq_param.chan_sel.rf_channel.single_rf.radio_freq;
444 }
445 else
446 {
447 // Frequency hopping: all frequencies of the frequency list are on the same band
448 // We take the first frequency of the list
449 radio_freq = l1pa_l1ps_com.transfer.aset->freq_param.freq_list.rf_chan_no.A[0];
450 }
451
452 calibrated_IL = (WORD16) (l1a_l1s_com.Scell_info.transfer_meas.input_level
453 - l1ctl_encode_delta1(radio_freq) - l1ctl_encode_delta2(radio_freq)
454 - l1a_l1s_com.last_input_level[serving_index].lna_off * l1ctl_get_lna_att(radio_freq));
455
456 if (calibrated_IL>INDEX_MAX) calibrated_IL = INDEX_MAX;
457
458 l1ctl_encode_lna((UWORD8)(calibrated_IL>>1), &(l1a_l1s_com.Scell_info.transfer_meas.lna_off), radio_freq);
459
460 } // End of "l1pctl_transfer_agc_init"
461
462 /*-------------------------------------------------------*/
463 /* l1pctl_transfer_agc_ctrl() */
464 /*-------------------------------------------------------*/
465 /* Description : */
466 /* =========== */
467 /* This function is used in the control phase of PDTCH/D */
468 /* to determine which AGC and lna_off must apply */
469 /*-------------------------------------------------------*/
470 void l1pctl_transfer_agc_ctrl(WORD8 *agc, UWORD8 *lna_off, UWORD16 radio_freq)
471 {
472 T_INPUT_LEVEL *selected_IL;
473 #if(L1_FF_MULTIBAND == 1)
474 UWORD16 operative_radio_freq;
475 #endif
476
477
478 // input_level selection
479 if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
480 {
481 // Beacon frequency input_level used for AGC processing
482 #if(L1_FF_MULTIBAND == 0)
483 selected_IL = &l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq
484 - l1_config.std.radio_freq_index_offset];
485
486 #else // L1_FF_MULTIBAND = 1 below
487
488 operative_radio_freq =
489 l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.Scell_info.radio_freq);
490 selected_IL = &(l1a_l1s_com.last_input_level[operative_radio_freq]);
491
492
493 #endif // #if(L1_FF_MULTIBAND == 0) else
494
495 }
496 else
497 {
498 // Daughter frequency input_level used for AGC processing
499 selected_IL = &l1a_l1s_com.Scell_info.transfer_meas;
500 }
501 *agc = Cust_get_agc_from_IL(radio_freq,selected_IL->input_level >> 1, MAX_ID);
502 *lna_off = selected_IL->lna_off;
503
504 // Store lna_off and input_level field used for current CTRL in order to be able
505 // to build IL from pm in READ phase.
506 l1a_l1s_com.Scell_used_IL.input_level = selected_IL->input_level;
507 l1a_l1s_com.Scell_used_IL.lna_off = *lna_off;
508
509 }
510
511 /*-------------------------------------------------------*/
512 /* l1pctl_npc_agc_read() */
513 /*-------------------------------------------------------*/
514 /* Description : */
515 /* =========== */
516 /* AGC algorithm in packet transfer used when */
517 /* NO POWER CONTROL is done by the BTS. */
518 /* This function is used during the read phase of PDTCH: */
519 /* 1- to determine the IL value for each timeslot in each*/
520 /* TDMA */
521 /* 2- to find the IL value to use for the next PDCH */
522 /* block */
523 /* */
524 /* Algorithm */
525 /* --------- */
526 /* For each timeslot i used for PDCH */
527 /* IL(i) = fct(used AGC, pm) */
528 /* if (beacon) */
529 /* ILmax_beacon = max(ILmax_beacon, IL(i)) */
530 /* else */
531 /* ILmax_others(i) = max(IL(i), ILmax_others(i)) */
532 /* */
533 /* If (burst_nb == 3) */
534 /* If (ILmax_beacon was found during the block) */
535 /* FIFO[beacon] updated with ILmax_beacon */
536 /* transfer_meas = max(FIFO[beacon]) */
537 /* Reset ILmax_beacon */
538 /* */
539 /* For each timeslot i used for PDCH */
540 /* if (CRC good) */
541 /* ILmax_correct = max(ILmax_correct, */
542 /* ILmax_others(i)) */
543 /* else */
544 /* ILmax_not_correct = max(ILmax_not_correct, */
545 /* ILmax_others(i)) */
546 /* */
547 /* If (no ILmax_correct was found) */
548 /* ILselected = ILmax_correct */
549 /* FNselected = current FN */
550 /* else */
551 /* DeltaFN = (current FN - FNselected) % MAX_FN */
552 /* */
553 /* if (DeltaFN < 78) */
554 /* ILweighted = ILselected * (1 - DeltaFN/78) */
555 /* - 120 * DeltaFN /78 */
556 /* */
557 /* if (ILweighted < -120) ILweighted = -120 */
558 /* if (ILmax_not_correct > ILweighted) */
559 /* ILselected = ILmax_not_correct */
560 /* FNselected = current FN */
561 /* else */
562 /* ILselected = -120 */
563 /* FNselected = current FN */
564 /* */
565 /* Reset ILmax_others[8] */
566 /* */
567 /* WARNING: in the layer 1 code, input levels IL(l1) use */
568 /* format 7.1: */
569 /* ********************* */
570 /* * IL(l1) = - 2 x IL * */
571 /* ********************* */
572 /* -> Reversed sign, reversed test conditions */
573 /* -> max replaced by min */
574 /* ex: if IL -120 dBm, IL(l1) = 240 */
575 /* */
576 /* Parameters */
577 /* ---------- */
578 /* "calibrated_IL[8]" */
579 /* contains the IL found on timeslots */
580 /* used for PDCH/D. These ILs can be used to process */
581 /* RXLEV values. */
582 /* */
583 /* "*pdsp_db_r_ptr" */
584 /* Pointer on the DSP DB Read page, used to extract */
585 /* pm values, burst number and timeslot allocated */
586 /* for downlink PDCH */
587 /* */
588 /* "*pdsp_ndb_ptr" */
589 /* Pointer on the DSP NDB page, used to extract the */
590 /* CRC value for each decoded burst */
591 /* */
592 /* Global parameters */
593 /* ----------------- */
594 /* "l1a_l1s_com.Scell_info.transfer_meas.input_level" */
595 /* "l1a_l1s_com.Scell_info.transfer_meas.lna_off" */
596 /* Used to store the ILselected and the associated */
597 /* lna_off value. */
598 /* */
599 /* "l1a_l1s_com.Scell_info.fn_select" */
600 /* Used to store the FNselected value. */
601 /* */
602 /* "l1a_l1s_com.last_input_level[freq index] */
603 /* .input_level */
604 /* .lna_off" */
605 /* Used to store the beacon input level and */
606 /* the associated lna_off value. */
607 /* */
608 /* "l1ps.transfer_beacon_buf[4]" */
609 /* FIFO[beacon] */
610 /* */
611 /* "l1ps.ILmin_beacon" */
612 /* "l1ps.ILmin_others[8]" */
613 /*-------------------------------------------------------*/
614 void l1pctl_npc_agc_read(UWORD8 calibrated_IL[8], T_DB_DSP_TO_MCU_GPRS *pdsp_db_r_ptr,
615 T_NDB_MCU_DSP_GPRS *pdsp_ndb_ptr)
616 {
617 UWORD8 ts;
618 UWORD8 rx_no = 0;
619 UWORD8 bit_mask = 0x80;
620 UWORD8 ILmin_correct = 255;
621 UWORD8 ILmin_not_correct = 255;
622 WORD8 delta1_freq, delta2_freq;
623 WORD16 delta_drp_gain=0;
624 UWORD16 radio_freq, lna_value;
625 WORD16 used_agc;
626 WORD32 serving_index;
627 #if (RF_FAM == 61)
628 UWORD16 arfcn;
629 #endif
630 UWORD8 lna_off;
631 UWORD16 dco_algo_ctl_pw_temp = 0;
632 UWORD8 if_ctl = 0;
633 #if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
634 UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GPRS;
635 #endif
636
637 #if(L1_FF_MULTIBAND == 0)
638 serving_index = l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset;
639
640 #else
641 serving_index = l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.Scell_info.radio_freq);
642 #endif
643
644
645 // Control phase parameters: same AGC, radio_freq, lna_off used for all PDTCH
646 // ***************************************************************************
647
648 // Get radio_freq on which the downlink block was received
649 radio_freq = l1a_l1s_com.dedic_set.radio_freq_dd;
650
651 // Compute calibration factors
652 delta1_freq = l1ctl_encode_delta1(radio_freq);
653 delta2_freq = l1ctl_encode_delta2(radio_freq);
654
655 // AGC used in the control phase (format F7.1)
656 used_agc = (Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.Scell_used_IL_dd.input_level >> 1, MAX_ID)) << 1;
657
658 // LNA attenuation
659 lna_value = l1a_l1s_com.Scell_used_IL_dd.lna_off * l1ctl_get_lna_att(radio_freq);
660
661 // Burst 0: Reset ILmin_beacon and ILmin_others
662 if(pdsp_db_r_ptr->d_burst_nb_gprs == 0)
663 {
664 l1ps.ILmin_beacon = 255; // Not valid
665
666 for (ts = 0; ts < 8; ts++)
667 {
668 l1ps.ILmin_others[ts] = (UWORD8) l1_config.params.il_min;
669 }
670 } // End if "burst 0"
671
672 // IL processing for each received burst
673 // **************************************
674
675 // For each timeslot on which a burst was received
676 for(ts = 0; ts < 8; ts ++)
677 {
678 if(pdsp_db_r_ptr->d_task_d_gprs & bit_mask)
679 {
680 WORD16 current_IL, current_calibrated_IL;
681 UWORD8 pm;
682
683 // IL = fct(pm, last_known_agc, lna_value, g_magic)
684 //-------------------------------------------------
685
686 pm = (UWORD8) ((pdsp_db_r_ptr->a_burst_pm_gprs[ts] & 0xffff) >> 5);
687
688 // current_IL processing
689 if (0==pm) // Check and filter illegal pm value by using last valid IL
690 {
691 if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
692 current_IL = l1a_l1s_com.last_input_level[serving_index].input_level
693 - lna_value;
694 else
695 current_IL = l1a_l1s_com.Scell_info.transfer_meas.input_level
696 - lna_value;
697 }
698 else
699 {
700
701 #if (RF_FAM == 61)
702 // DRP correction
703 #if (L1_FF_MULTIBAND == 0)
704 arfcn = Convert_l1_radio_freq(radio_freq);
705 #else
706 arfcn=radio_freq;
707 #endif
708
709 #if (CODE_VERSION != SIMULATION)
710
711 cust_get_if_dco_ctl_algo(&dco_algo_ctl_pw_temp, &if_ctl, (UWORD8) L1_IL_VALID ,
712 l1a_l1s_com.Scell_used_IL_dd.input_level,
713 radio_freq,if_threshold);
714 lna_off = l1a_l1s_com.Scell_used_IL_dd.lna_off;
715 delta_drp_gain = drp_gain_correction(arfcn, lna_off, used_agc); // F7.1 format
716 if(if_ctl == IF_100KHZ_DSP){
717 delta_drp_gain += SCF_ATTENUATION_LIF_100KHZ;
718 }
719 else{ /* i.e. if_ctl = IF_120KHZ_DSP*/
720 delta_drp_gain += SCF_ATTENUATION_LIF_120KHZ;
721 }
722
723 #endif
724 #endif
725
726 current_IL = -(pm - (used_agc - delta_drp_gain) + lna_value - l1ctl_get_g_magic(radio_freq));
727 }
728
729 // Calibrated IL processing
730 current_calibrated_IL = current_IL - delta1_freq - delta2_freq;
731
732 // Protect IL stores against overflow
733 if(current_calibrated_IL>INDEX_MAX)
734 current_calibrated_IL=INDEX_MAX;
735 if (current_IL>INDEX_MAX)
736 current_IL=INDEX_MAX;
737
738 calibrated_IL[ts] = (UWORD8)(current_calibrated_IL);
739
740 // Keep ILmax
741 if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
742 {
743 // Beacon frequency
744 l1ps.ILmin_beacon = min((UWORD8) current_IL, l1ps.ILmin_beacon);
745 }
746 else
747 {
748 // Daughter frequency
749 l1ps.ILmin_others[ts] = min((UWORD8) current_IL,l1ps.ILmin_others[ts]);
750 }
751
752 // Input Level selection among ILmax found on each timeslot during the block (when burst = 3)
753 // *******************************************************************************************
754
755 if(pdsp_db_r_ptr->d_burst_nb_gprs == 3)
756 {
757 // If CRC good
758 if (!(pdsp_ndb_ptr->a_dd_gprs[rx_no][0] & 0x0100))
759 {
760 // Find the min found IL for blocks that were correctly received
761 ILmin_correct = min(l1ps.ILmin_others[ts],ILmin_correct);
762 }
763 // If CRC bad
764 else
765 {
766 // Find the min found IL for blocks that were not correctly received
767 ILmin_not_correct = min(l1ps.ILmin_others[ts],ILmin_not_correct);
768 }
769 } // End if "burst = 3"
770
771 // Next downlink block
772 rx_no ++;
773
774 } // End if "timeslot used for downlink PDCH"
775
776 // Next timeslot
777 bit_mask >>= 1;
778 } // End for "each timeslot...."
779
780
781 // IL selection for the next block if burst = 3
782 // **********************************************
783
784 if(pdsp_db_r_ptr->d_burst_nb_gprs == 3)
785 {
786 WORD16 new_calibrated_IL;
787
788 // Beacon frequency input level updating
789 //--------------------------------------
790
791 // If a PDCH has been received on the beacon
792 if (l1ps.ILmin_beacon != 255)
793 {
794 UWORD8 i, new_IL;
795
796 // FIFO management
797 for (i=3;i>0;i--)
798 l1a_l1s_com.Scell_info.buff_beacon[i] = l1a_l1s_com.Scell_info.buff_beacon[i-1];
799 l1a_l1s_com.Scell_info.buff_beacon[0] = l1ps.ILmin_beacon;
800
801 // Find min IL in FIFO
802 new_IL = l1ctl_find_max(l1a_l1s_com.Scell_info.buff_beacon, 4);
803
804 // Input levels are always stored with lna_on
805
806 // lna_off processing
807 new_calibrated_IL = (WORD16) (new_IL - l1ctl_encode_delta1(l1a_l1s_com.Scell_info.radio_freq) - l1ctl_encode_delta2(l1a_l1s_com.Scell_info.radio_freq));
808
809 if (new_calibrated_IL>INDEX_MAX) new_calibrated_IL = INDEX_MAX;
810
811 l1ctl_encode_lna((UWORD8)(new_calibrated_IL>>1),
812 &(l1a_l1s_com.last_input_level[serving_index].lna_off),
813 l1a_l1s_com.Scell_info.radio_freq);
814
815 l1a_l1s_com.last_input_level[serving_index].input_level = new_IL +
816 l1a_l1s_com.last_input_level[serving_index].lna_off *
817 l1ctl_get_lna_att(l1a_l1s_com.Scell_info.radio_freq);
818
819 } // End of "beacon frequency input level updating"
820
821 // Daughter frequencies input level updating
822 //------------------------------------------
823
824 // If at least one block was correctly received
825 // (Note: ILs truncated to 240 so 255 isn't valid)
826 if (ILmin_correct != 255)
827 {
828 // Select the min input level found on correctly received blocks
829 l1a_l1s_com.Scell_info.transfer_meas.input_level = ILmin_correct;
830 l1ps.fn_select = l1s.actual_time.fn;
831
832 // Algorithm switch to "TRACK" phase if it was in "SEARCH" phase
833 l1ps.phase = TRACK;
834 }
835
836 // No block was correctly received
837 else
838 {
839 UWORD8 input_level_ref = l1a_l1s_com.Scell_info.transfer_meas.input_level
840 - l1a_l1s_com.Scell_info.transfer_meas.lna_off *
841 l1ctl_get_lna_att(radio_freq);
842 // SEARCH phase
843 if (l1ps.phase == SEARCH)
844 {
845 // If measured level superior to currently tracket level, switch to TRACK mode
846 if (input_level_ref > ILmin_not_correct)
847 l1ps.phase = TRACK;
848
849 // Select the min input level found on badly received blocks
850 l1a_l1s_com.Scell_info.transfer_meas.input_level = ILmin_not_correct;
851 l1ps.fn_select = l1s.actual_time.fn;
852 }
853
854 // TRACK phase
855 else
856 {
857 // If the IL found on incorrect block is lower than current wanted IL
858 if (ILmin_not_correct < input_level_ref)
859 {
860 // Select the new IL
861 l1a_l1s_com.Scell_info.transfer_meas.input_level = ILmin_not_correct;
862 l1ps.fn_select = l1s.actual_time.fn;
863 }
864
865 // If the IL found on incorrect block is higher than current wanted IL
866 else
867 {
868 UWORD32 delta_fn;
869
870 // delta_fn processing for IL selection forgetting factor
871 delta_fn = l1s.actual_time.fn - l1ps.fn_select;
872
873 // MAX_FN modulo management
874 if (l1s.actual_time.fn < l1ps.fn_select)
875 delta_fn += MAX_FN;
876
877 // If the last selected IL is more recent than 72 frames
878 //
879 // |....|R...............................C|....|
880 // ^ ^
881 // fn_selected IL reset to -120
882 // <-------------------------------------->
883 // 312
884 // 306 = 312 - 4 (block_size) - 1 (Read phase fn delay) - 1 (Control phase fn advance)
885 if (delta_fn > 306)
886 {
887 WORD16 input_level;
888
889 // IL initialized to "beacon level - Pb"
890 input_level = (WORD16)
891 ((l1a_l1s_com.last_input_level[serving_index].input_level +
892 l1a_l1s_com.Scell_info.pb) -
893 (l1a_l1s_com.last_input_level[serving_index].lna_off *
894 l1ctl_get_lna_att(l1a_l1s_com.Scell_info.radio_freq)));
895
896 if (input_level>INDEX_MAX) input_level = INDEX_MAX;
897 l1a_l1s_com.Scell_info.transfer_meas.input_level = (UWORD8)input_level;
898
899 l1ps.fn_select = l1s.actual_time.fn;
900 // Returns to "SEARCH" phase
901 l1ps.phase = SEARCH;
902 }
903 else
904 {
905 WORD16 input_level;
906
907 input_level = l1a_l1s_com.Scell_info.transfer_meas.input_level -
908 l1a_l1s_com.Scell_info.transfer_meas.lna_off *
909 l1ctl_get_lna_att(l1ps.read_param.radio_freq_for_lna);
910
911 if (input_level>INDEX_MAX) input_level = INDEX_MAX;
912
913 l1a_l1s_com.Scell_info.transfer_meas.input_level = (UWORD8)input_level;
914 }
915 } // End if the IL found on incorrect block is higher than current wanted IL
916 } // End of "track phase"
917 } // End if no block correctly received
918
919 // lna_off processing
920 new_calibrated_IL = (WORD16) (l1a_l1s_com.Scell_info.transfer_meas.input_level - l1ctl_encode_delta1(l1ps.read_param.radio_freq_for_lna));
921 if (new_calibrated_IL>INDEX_MAX) new_calibrated_IL = INDEX_MAX;
922
923 l1ctl_encode_lna((UWORD8)(new_calibrated_IL>>1), &(l1a_l1s_com.Scell_info.transfer_meas.lna_off), l1ps.read_param.radio_freq_for_lna);
924
925 l1a_l1s_com.Scell_info.transfer_meas.input_level +=
926 l1a_l1s_com.Scell_info.transfer_meas.lna_off *
927 l1ctl_get_lna_att(l1ps.read_param.radio_freq_for_lna);
928 } // End if "burst = 3"
929
930 } // End of "l1pctl_npc_agc_read"
931
932 /*-------------------------------------------------------*/
933 /* l1pctl_dpcma_agc_read() */
934 /*-------------------------------------------------------*/
935 /* Description : */
936 /* =========== */
937 /* AGC algorithm in packet transfer used when the BTS */
938 /* use DOWNLINK POWER CONTROL mode A. */
939 /* This function is used during the read phase of PDTCH: */
940 /* 1- to determine the IL value for each timeslot in each*/
941 /* TDMA */
942 /* 2- to find the IL value to use for the next PDCH */
943 /* block */
944 /* */
945 /* Algorithm */
946 /* --------- */
947 /* For each timeslot i used for PDCH */
948 /* IL(i) = fct(used AGC, pm) */
949 /* if (beacon) */
950 /* ILmax_beacon = max(ILmax_beacon, IL(i)) */
951 /* else */
952 /* ILmax_others(i) = max(IL(i), ILmax_others(i)) */
953 /* */
954 /* If (burst_nb == 3) */
955 /* */
956 /* For each timeslot i used for PDCH */
957 /* if (CRC good) and */
958 /* ((PR_MODE A) or (PR_MODE B and TFI good)) */
959 /* ILmax = max(ILmax, ILmax_others(i) + P0 + PR(i))*/
960 /* */
961 /* ILmax=max(ILmax, ILmax_beacon) */
962 /* FIFO[beacon] updated with ILmax */
963 /* last_input_level[serving beacon] = max(FIFO[beacon])*/
964 /* transfer_meas = max(FIFO[beacon]) - P0 - 5 */
965 /* */
966 /* Reset ILmax_others[8] and ILmax_beacon */
967 /* */
968 /* WARNING: in the layer 1 code, input levels IL(l1) use */
969 /* format 7.1: */
970 /* ********************* */
971 /* * IL(l1) = - 2 x IL * */
972 /* ********************* */
973 /* -> Reversed sign, reversed test conditions */
974 /* -> max replaced by min */
975 /* ex: if IL -120 dBm, IL(l1) = 240 */
976 /* */
977 /* Parameters */
978 /* ---------- */
979 /* "calibrated_IL[8]" */
980 /* contains the IL found on timeslots */
981 /* used for PDCH/D. These ILs can be used to process */
982 /* RXLEV values. */
983 /* */
984 /* "*pdsp_db_r_ptr" */
985 /* Pointer on the DSP DB Read page, used to extract */
986 /* pm values, burst number and timeslot allocated */
987 /* for downlink PDCH */
988 /* */
989 /* "*pdsp_ndb_ptr" */
990 /* Pointer on the DSP NDB page, used to extract the */
991 /* CRC value for each decoded burst */
992 /* */
993 /* Global parameters */
994 /* ----------------- */
995 /* "l1a_l1s_com.Scell_info.transfer_meas.input_level" */
996 /* "l1a_l1s_com.Scell_info.transfer_meas.lna_off" */
997 /* Used to store the ILselected and the associated */
998 /* lna_off value. */
999 /* */
1000 /* "l1a_l1s_com.last_input_level[freq. index] */
1001 /* .input_level */
1002 /* .lna_off" */
1003 /* Used to store the beacon input level and */
1004 /* the associated lna_off value. */
1005 /* */
1006 /* "l1ps.transfer_beacon_buf[4]" */
1007 /* FIFO[beacon] */
1008 /* */
1009 /* "l1ps.ILmin_beacon" */
1010 /* "l1ps.ILmin_others[8]" */
1011 /*-------------------------------------------------------*/
1012 void l1pctl_dpcma_agc_read(UWORD8 calibrated_IL[8], T_DB_DSP_TO_MCU_GPRS *pdsp_db_r_ptr,
1013 T_NDB_MCU_DSP_GPRS *pdsp_ndb_ptr, UWORD8 pr_table[8])
1014 {
1015 UWORD8 ts = 0;
1016 UWORD8 rx_no = 0;
1017 UWORD8 bit_mask = 0x80;
1018 UWORD8 IL_norm_min = 255;
1019 WORD8 delta1_freq, delta2_freq;
1020 WORD16 delta_drp_gain=0;
1021 UWORD16 radio_freq, lna_value;
1022 WORD16 used_agc;
1023 WORD32 serving_index;
1024 #if (RF_FAM == 61)
1025 UWORD16 arfcn;
1026 #endif
1027 UWORD8 lna_off;
1028 UWORD16 dco_algo_ctl_pw_temp = 0;
1029 UWORD8 if_ctl = 0;
1030 #if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
1031 UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GPRS;
1032 #endif
1033
1034 #if(L1_FF_MULTIBAND == 0)
1035 serving_index = l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset;
1036
1037 #else
1038 serving_index = l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.Scell_info.radio_freq);
1039 #endif
1040
1041
1042 // Control phase parameters: same AGC, radio_freq, lna_off used for all PDTCH
1043 // ***************************************************************************
1044
1045 // Get radio_freq on which the downlink block was received
1046 radio_freq = l1a_l1s_com.dedic_set.radio_freq_dd;
1047
1048 // Compute calibration factors
1049 delta1_freq = l1ctl_encode_delta1(radio_freq);
1050 delta2_freq = l1ctl_encode_delta2(radio_freq);
1051
1052 // Last known AGC (format F7.1)
1053 used_agc = (Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.Scell_used_IL_dd.input_level >> 1, MAX_ID)) << 1;
1054
1055 // LNA attenuation
1056 lna_value = l1a_l1s_com.Scell_used_IL_dd.lna_off * l1ctl_get_lna_att(radio_freq);
1057
1058 // Burst 0: Reset ILmin_beacon and ILmin_others
1059 if(pdsp_db_r_ptr->d_burst_nb_gprs == 0)
1060 {
1061 l1ps.ILmin_beacon = 255; // Not valid
1062
1063 for (ts = 0; ts < 8; ts++)
1064 {
1065 l1ps.ILmin_others[ts] = 255; // Not valid
1066 }
1067 }
1068
1069 // IL processing for each received burst
1070 // **************************************
1071
1072 #if (RF_FAM == 61)
1073 // DRP correction
1074 #if (L1_FF_MULTIBAND == 0)
1075 arfcn = Convert_l1_radio_freq(radio_freq);
1076 #else
1077 arfcn=radio_freq;
1078 #endif
1079
1080 #if (CODE_VERSION != SIMULATION)
1081
1082 cust_get_if_dco_ctl_algo(&dco_algo_ctl_pw_temp, &if_ctl, (UWORD8) L1_IL_VALID ,
1083 l1a_l1s_com.Scell_used_IL_dd.input_level,
1084 radio_freq, if_threshold);
1085 lna_off = l1a_l1s_com.Scell_used_IL_dd.lna_off;
1086 delta_drp_gain = drp_gain_correction(arfcn, lna_off, used_agc); // F7.1 format
1087
1088 if(if_ctl == IF_100KHZ_DSP){
1089 delta_drp_gain += SCF_ATTENUATION_LIF_100KHZ;
1090 }
1091 else{ /* i.e. if_ctl = IF_120KHZ_DSP*/
1092 delta_drp_gain += SCF_ATTENUATION_LIF_120KHZ;
1093 }
1094
1095 #endif
1096 #endif
1097
1098 // For each timeslot on which a burst was received
1099 for(ts = 0; ts < 8; ts ++)
1100 {
1101 if(pdsp_db_r_ptr->d_task_d_gprs & bit_mask)
1102 {
1103 WORD16 current_IL, current_calibrated_IL;
1104 UWORD8 pm;
1105
1106 // IL = fct(pm, last_known_agc, lna_value, g_magic)
1107 //-------------------------------------------------
1108
1109 pm = (UWORD8) ((pdsp_db_r_ptr->a_burst_pm_gprs[ts] & 0xffff) >> 5);
1110
1111 // current_IL processing
1112 if (0==pm) // Check and filter illegal pm value by using last valid IL
1113 {
1114 current_IL = l1a_l1s_com.last_input_level[serving_index].input_level
1115 - lna_value;
1116
1117 if (radio_freq != l1a_l1s_com.Scell_info.radio_freq)
1118 current_IL += (l1ps.read_param.dl_pwr_ctl.p0 + 10);
1119 }
1120 else
1121 {
1122 current_IL = -(pm - (used_agc - delta_drp_gain) + lna_value - l1ctl_get_g_magic(radio_freq));
1123 }
1124
1125 // Calibrated IL processing
1126 current_calibrated_IL = current_IL - delta1_freq - delta2_freq;
1127
1128 // Protect IL stores against overflow
1129 if(current_calibrated_IL>INDEX_MAX)
1130 current_calibrated_IL=INDEX_MAX;
1131 if (current_IL>INDEX_MAX)
1132 current_IL=INDEX_MAX;
1133
1134 calibrated_IL[ts] = (UWORD8)(current_calibrated_IL);
1135
1136 // Keep the minimum IL
1137 if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
1138 {
1139 // Beacon frequency
1140 l1ps.ILmin_beacon = min((UWORD8) current_IL,l1ps.ILmin_beacon);
1141 }
1142 else
1143 {
1144 // Daughter frequency
1145 l1ps.ILmin_others[ts] = min((UWORD8) current_IL, l1ps.ILmin_others[ts]);
1146 }
1147
1148 // Input Level selection among ILmax found on each timeslot during the block (when burst = 3)
1149 //-------------------------------------------------------------------------------------------
1150
1151 if(pdsp_db_r_ptr->d_burst_nb_gprs == 3)
1152 {
1153 // If CRC good
1154 if (!(pdsp_ndb_ptr->a_dd_gprs[rx_no][0] & 0x0100))
1155 {
1156 // If ((PR_MODE A and TFI good) or (PR_MODE B)) AND PR != 0 [Not usable])
1157 if (((l1ps.read_param.dl_pwr_ctl.pr_mode != 0) || (!(pr_table[ts] & 0x80)))
1158 && ((pr_table[ts] & 0x1f) != 0))
1159 {
1160 if (l1ps.ILmin_others[ts] != 255)
1161 {
1162 UWORD8 IL_norm;
1163
1164 // IL normalization to beacon (ILnorm = ILmax_others(ts) - P0 - PR)
1165 IL_norm = l1ps.ILmin_others[ts] - l1ps.read_param.dl_pwr_ctl.p0 - ((pr_table[ts] & 0x1f) << 1);
1166
1167 // Update IL_min with the minimum found IL
1168 IL_norm_min = min(IL_norm, IL_norm_min);
1169 }
1170 }
1171 } // End if "CRC good"
1172
1173 } // End if "burst = 3"
1174
1175 // Next downlink block
1176 rx_no ++;
1177
1178 } // End if "timeslot used for downlink PDCH"
1179
1180 // Next timeslot
1181 bit_mask >>= 1;
1182
1183 } // End for "each timeslot...."
1184
1185
1186 // IL selection for the next block if burst = 3
1187 // **********************************************
1188
1189 if(pdsp_db_r_ptr->d_burst_nb_gprs == 3)
1190 {
1191 UWORD8 i, new_IL;
1192 UWORD16 input_level;
1193 WORD16 new_calibrated_IL;
1194
1195 // Select the minimum IL between minimum IL found on daughter frequencies (normalized to beacon)
1196 // and minimum IL found on the beacon
1197 IL_norm_min = min(IL_norm_min, l1ps.ILmin_beacon);
1198
1199 // If a valid IL has been found
1200 if (IL_norm_min != 255)
1201 {
1202 // FIFO management
1203 for (i=3;i>0;i--)
1204 l1a_l1s_com.Scell_info.buff_beacon[i] = l1a_l1s_com.Scell_info.buff_beacon[i-1];
1205
1206 l1a_l1s_com.Scell_info.buff_beacon[0] = IL_norm_min;
1207
1208 // last_input_level[serving beacon] updating
1209 //------------------------------------------
1210
1211 // Find min IL in FIFO
1212 new_IL = l1ctl_find_max(l1a_l1s_com.Scell_info.buff_beacon,4);
1213
1214 // Input levels are always stored with lna_on
1215
1216 // lna_off processing
1217 new_calibrated_IL = (WORD16) (new_IL - l1ctl_encode_delta1(l1a_l1s_com.Scell_info.radio_freq) - l1ctl_encode_delta2(l1a_l1s_com.Scell_info.radio_freq));
1218 if (new_calibrated_IL>INDEX_MAX) new_calibrated_IL = INDEX_MAX;
1219
1220 l1ctl_encode_lna((UWORD8)(new_calibrated_IL >> 1),
1221 &(l1a_l1s_com.last_input_level[serving_index].lna_off),
1222 l1a_l1s_com.Scell_info.radio_freq);
1223
1224 l1a_l1s_com.last_input_level[serving_index].input_level = new_IL +
1225 l1a_l1s_com.last_input_level[serving_index].lna_off *
1226 l1ctl_get_lna_att(l1a_l1s_com.Scell_info.radio_freq);
1227 }
1228
1229 // transfer_meas updating
1230 //-----------------------
1231
1232 // IL = (min IL in FIFO) + P0 + 10 (PR = 5 format 7.1)
1233 // Input levels are always stored with lna_on
1234 input_level = l1a_l1s_com.last_input_level[serving_index].input_level
1235 - l1a_l1s_com.last_input_level[serving_index].lna_off *
1236 l1ctl_get_lna_att(l1a_l1s_com.Scell_info.radio_freq)
1237 + l1ps.read_param.dl_pwr_ctl.p0 + 10;
1238
1239 // IL_2_AGC_xx array size
1240 if (input_level>INDEX_MAX) input_level = INDEX_MAX;
1241
1242 // lna_off processing
1243 new_calibrated_IL = (WORD16) (input_level - l1ctl_encode_delta1(l1ps.read_param.radio_freq_for_lna));
1244
1245 if (new_calibrated_IL>INDEX_MAX) new_calibrated_IL = INDEX_MAX;
1246
1247 l1ctl_encode_lna((UWORD8)(new_calibrated_IL>>1), &(l1a_l1s_com.Scell_info.transfer_meas.lna_off), l1ps.read_param.radio_freq_for_lna);
1248
1249 l1a_l1s_com.Scell_info.transfer_meas.input_level = input_level +
1250 l1a_l1s_com.Scell_info.transfer_meas.lna_off *
1251 l1ctl_get_lna_att(l1ps.read_param.radio_freq_for_lna);
1252 } // End if "burst = 3"
1253
1254 } // End of "l1pctl_dpcma_agc_read"
1255
1256 /*-------------------------------------------------------*/
1257 /* l1pctl_dpcmb_agc_read() */
1258 /*-------------------------------------------------------*/
1259 /* Description : */
1260 /* =========== */
1261 /* AGC algorithm in packet transfer used when the BTS */
1262 /* use DOWNLINK POWER CONTROL mode B. */
1263 /* This function is used during the read phase of PDTCH: */
1264 /* 1- to determine the IL value for each timeslot in each*/
1265 /* TDMA */
1266 /* 2- to find the IL value to use for the next PDCH */
1267 /* block */
1268 /* */
1269 /* Algorithm */
1270 /* --------- */
1271 /* For each timeslot i used for PDCH */
1272 /* IL(i) = fct(used AGC, pm) */
1273 /* if (beacon) */
1274 /* ILmax_beacon = max(ILmax_beacon, IL(i)) */
1275 /* else */
1276 /* ILmax_others(i) = max(IL(i), ILmax_others(i)) */
1277 /* */
1278 /* If (burst_nb == 3) */
1279 /* */
1280 /* For each timeslot i used for PDCH */
1281 /* if (CRC good) */
1282 /* if (TFI good) last_PR_good = PR(i) */
1283 /* if ((PR_MODE A) or (PR_MODE B and TFI good)) */
1284 /* ILmax = max(ILmax, ILmax_others(i) */
1285 /* + P0 + PR(i)) */
1286 /* */
1287 /* ILmax=max(ILmax, ILmax_beacon) */
1288 /* FIFO[beacon] updated with ILmax */
1289 /* last_input_level[serving beacon] = max(FIFO[beacon])*/
1290 /* transfer_meas = max(FIFO[beacon]) - last_PR_good */
1291 /* */
1292 /* Reset ILmax_others[8] and ILmax_beacon */
1293 /* */
1294 /* WARNING: in the layer 1 code, input levels IL(l1) use */
1295 /* format 7.1: */
1296 /* ********************* */
1297 /* * IL(l1) = - 2 x IL * */
1298 /* ********************* */
1299 /* -> Reversed sign, reversed test conditions */
1300 /* -> max replaced by min */
1301 /* ex: if IL -120 dBm, IL(l1) = 240 */
1302 /* */
1303 /* Parameters */
1304 /* ---------- */
1305 /* "calibrated_IL[8]" */
1306 /* contains the IL found on timeslots */
1307 /* used for PDCH/D. These ILs can be used to process */
1308 /* RXLEV values. */
1309 /* */
1310 /* "*pdsp_db_r_ptr" */
1311 /* Pointer on the DSP DB Read page, used to extract */
1312 /* pm values, burst number and timeslot allocated */
1313 /* for downlink PDCH */
1314 /* */
1315 /* "*pdsp_ndb_ptr" */
1316 /* Pointer on the DSP NDB page, used to extract the */
1317 /* CRC value for each decoded burst */
1318 /* */
1319 /* Global parameters */
1320 /* ----------------- */
1321 /* "l1a_l1s_com.Scell_info.transfer_meas.input_level" */
1322 /* "l1a_l1s_com.Scell_info.transfer_meas.lna_off" */
1323 /* Used to store the ILselected and the associated */
1324 /* lna_off value. */
1325 /* */
1326 /* "l1a_l1s_com.last_input_level[freq. index] */
1327 /* .input_level */
1328 /* .lna_off" */
1329 /* Used to store the beacon input level and */
1330 /* the associated lna_off value. */
1331 /* */
1332 /* "l1ps.transfer_beacon_buf[4]" */
1333 /* FIFO[beacon] */
1334 /* */
1335 /* "l1ps.ILmin_beacon" */
1336 /* "l1ps.ILmin_others[8]" */
1337 /*-------------------------------------------------------*/
1338 void l1pctl_dpcmb_agc_read(UWORD8 calibrated_IL[8], T_DB_DSP_TO_MCU_GPRS *pdsp_db_r_ptr,
1339 T_NDB_MCU_DSP_GPRS *pdsp_ndb_ptr, UWORD8 pr_table[8])
1340 {
1341 UWORD8 ts = 0;
1342 UWORD8 rx_no = 0;
1343 UWORD8 bit_mask = 0x80;
1344 UWORD8 IL_norm_min = 255;
1345 WORD8 delta1_freq, delta2_freq;
1346 WORD16 delta_drp_gain=0;
1347 UWORD16 radio_freq, lna_value;
1348 WORD16 used_agc;
1349 WORD32 serving_index;
1350 #if (RF_FAM == 61)
1351 UWORD16 arfcn;
1352 #endif
1353 UWORD8 lna_off;
1354 UWORD16 dco_algo_ctl_pw_temp = 0;
1355 UWORD8 if_ctl = 0;
1356 #if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
1357 UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GPRS;
1358 #endif
1359
1360 #if(L1_FF_MULTIBAND == 0)
1361 serving_index = l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset;
1362 #else
1363 serving_index = l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.Scell_info.radio_freq);
1364 #endif
1365
1366
1367 // Control phase parameters: same AGC, radio_freq, lna_off used for all PDTCH
1368 // ***************************************************************************
1369
1370 // Get radio_freq on which the downlink block was received
1371 radio_freq = l1a_l1s_com.dedic_set.radio_freq_dd;
1372
1373 // Compute calibration factors
1374 delta1_freq = l1ctl_encode_delta1(radio_freq);
1375 delta2_freq = l1ctl_encode_delta2(radio_freq);
1376
1377 // Last known AGC (format F7.1)
1378 used_agc = (Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.Scell_used_IL_dd.input_level >> 1, MAX_ID)) << 1;
1379
1380 // LNA attenuation
1381 lna_value = l1a_l1s_com.Scell_used_IL_dd.lna_off * l1ctl_get_lna_att(radio_freq);
1382
1383 // Burst 0: Reset ILmin_beacon and ILmin_others
1384 if(pdsp_db_r_ptr->d_burst_nb_gprs == 0)
1385 {
1386 l1ps.ILmin_beacon = 255; // Not valid
1387
1388 for (ts = 0; ts < 8; ts++)
1389 {
1390 l1ps.ILmin_others[ts] = 255; // Not valid
1391 }
1392 }
1393
1394 // IL processing for each received burst
1395 // **************************************
1396
1397 // For each timeslot on which a burst was received
1398 for(ts = 0; ts < 8; ts ++)
1399 {
1400 if(pdsp_db_r_ptr->d_task_d_gprs & bit_mask)
1401 {
1402 WORD16 current_IL, current_calibrated_IL;
1403 UWORD8 pm;
1404
1405 // IL = fct(pm, last_known_agc, lna_value, g_magic)
1406 //-------------------------------------------------
1407
1408 pm = (UWORD8) ((pdsp_db_r_ptr->a_burst_pm_gprs[ts] & 0xffff) >> 5);
1409
1410 // current_IL processing
1411 if (0==pm) // Check and filter illegal pm value by using last valid IL
1412 {
1413 current_IL = l1a_l1s_com.last_input_level[serving_index].input_level
1414 - lna_value;
1415
1416 if (radio_freq != l1a_l1s_com.Scell_info.radio_freq)
1417 current_IL += (l1ps.last_PR_good);
1418 }
1419 else
1420 {
1421
1422 #if (RF_FAM == 61)
1423 // DRP correction
1424 #if (L1_FF_MULTIBAND == 0)
1425 arfcn = Convert_l1_radio_freq(radio_freq);
1426 #else
1427 arfcn=radio_freq;
1428 #endif
1429
1430 #if (CODE_VERSION != SIMULATION)
1431
1432
1433 cust_get_if_dco_ctl_algo(&dco_algo_ctl_pw_temp, &if_ctl, (UWORD8) L1_IL_VALID ,
1434 l1a_l1s_com.Scell_used_IL_dd.input_level,
1435 radio_freq, if_threshold);
1436 lna_off = l1a_l1s_com.Scell_used_IL_dd.lna_off;
1437 delta_drp_gain = drp_gain_correction(arfcn, lna_off, used_agc); // F7.1 format
1438
1439 if(if_ctl == IF_100KHZ_DSP){
1440 delta_drp_gain += SCF_ATTENUATION_LIF_100KHZ;
1441 }
1442 else{ /* i.e. if_ctl = IF_120KHZ_DSP*/
1443 delta_drp_gain += SCF_ATTENUATION_LIF_120KHZ;
1444 }
1445
1446
1447 #endif
1448 #endif
1449
1450 current_IL = -(pm - ( used_agc - delta_drp_gain) + lna_value - l1ctl_get_g_magic(radio_freq));
1451 }
1452
1453 // Calibrated IL processing
1454 current_calibrated_IL = current_IL - delta1_freq - delta2_freq;
1455
1456 // Protect IL stores against overflow
1457 if(current_calibrated_IL>INDEX_MAX)
1458 current_calibrated_IL=INDEX_MAX;
1459 if (current_IL>INDEX_MAX)
1460 current_IL=INDEX_MAX;
1461
1462 calibrated_IL[ts] = (UWORD8)(current_calibrated_IL);
1463
1464 // Keep the minimum IL
1465 if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
1466 {
1467 // Beacon frequency
1468 l1ps.ILmin_beacon = min((UWORD8) current_IL,l1ps.ILmin_beacon);
1469 }
1470 else
1471 {
1472 // Daughter frequency
1473 l1ps.ILmin_others[ts] = min((UWORD8) current_IL, l1ps.ILmin_others[ts]);
1474 }
1475
1476 // Input Level selection among ILmax found on each timeslot during the block (when burst = 3)
1477 //-------------------------------------------------------------------------------------------
1478
1479 if(pdsp_db_r_ptr->d_burst_nb_gprs == 3)
1480 {
1481 // If CRC good
1482 if (!(pdsp_ndb_ptr->a_dd_gprs[rx_no][0] & 0x0100))
1483 {
1484 // If ((PR_MODE A and TFI good) or (PR_MODE B))
1485 if ((l1ps.read_param.dl_pwr_ctl.pr_mode != 0) || (!(pr_table[ts] & 0x80)))
1486 {
1487
1488 // If TFI good
1489 if (!(pr_table[ts] & 0x80))
1490 {
1491 // Memorize decoded PR
1492 l1ps.last_PR_good = ((pr_table[ts] & 0x1f) << 1);
1493 }
1494
1495 if (l1ps.ILmin_others[ts] != 255)
1496 {
1497 UWORD8 IL_norm;
1498
1499 // IL normalization to beacon (ILnorm = ILmax_others(ts) - PR)
1500 IL_norm = l1ps.ILmin_others[ts] - ((pr_table[ts] & 0x1f) << 1);
1501
1502 // Update IL_min with the minimum found IL
1503 IL_norm_min = min(IL_norm, IL_norm_min);
1504 }
1505 }
1506 } // End if "CRC good"
1507
1508 } // End if "burst = 3"
1509
1510 // Next downlink block
1511 rx_no ++;
1512
1513 } // End if "timeslot used for downlink PDCH"
1514
1515 // Next timeslot
1516 bit_mask >>= 1;
1517
1518 } // End for "each timeslot...."
1519
1520
1521 // IL selection for the next block if burst = 3
1522 // **********************************************
1523
1524 if(pdsp_db_r_ptr->d_burst_nb_gprs == 3)
1525 {
1526 UWORD8 i, new_IL;
1527 UWORD16 input_level;
1528 WORD16 new_calibrated_IL;
1529
1530 // Select the minimum IL between minimum IL found on daughter frequencies (normalized to beacon)
1531 // and minimum IL found on the beacon
1532 IL_norm_min = min(IL_norm_min, l1ps.ILmin_beacon);
1533
1534 // If a valid IL has been found
1535 if (IL_norm_min != 255)
1536 {
1537 // FIFO management
1538 for (i=3;i>0;i--)
1539 l1a_l1s_com.Scell_info.buff_beacon[i] = l1a_l1s_com.Scell_info.buff_beacon[i-1];
1540
1541 l1a_l1s_com.Scell_info.buff_beacon[0] = IL_norm_min;
1542
1543 // last_input_level[serving beacon] updating
1544 //------------------------------------------
1545
1546 // Find min IL in FIFO
1547 new_IL = l1ctl_find_max(l1a_l1s_com.Scell_info.buff_beacon,4);
1548
1549 // Input levels are always stored with lna_on
1550
1551 // lna_off processing
1552 new_calibrated_IL = (WORD16) (new_IL - l1ctl_encode_delta1(l1a_l1s_com.Scell_info.radio_freq) - l1ctl_encode_delta2(l1a_l1s_com.Scell_info.radio_freq));
1553
1554 if (new_calibrated_IL>INDEX_MAX) new_calibrated_IL = INDEX_MAX;
1555
1556 l1ctl_encode_lna((UWORD8)(new_calibrated_IL >> 1),
1557 &(l1a_l1s_com.last_input_level[serving_index].lna_off),
1558 l1a_l1s_com.Scell_info.radio_freq);
1559
1560 l1a_l1s_com.last_input_level[serving_index].input_level = new_IL +
1561 l1a_l1s_com.last_input_level[serving_index].lna_off *
1562 l1ctl_get_lna_att(l1a_l1s_com.Scell_info.radio_freq);
1563 }
1564
1565 // transfer_meas updating
1566 //-----------------------
1567
1568 // IL = (min IL in FIFO) + PR (Middle of the range specified by the last decoded PR with CRC and TFI good)
1569 // Input levels are always stored with lna_on
1570 input_level = l1a_l1s_com.last_input_level[serving_index].input_level
1571 - l1a_l1s_com.last_input_level[serving_index].lna_off *
1572 l1ctl_get_lna_att(l1a_l1s_com.Scell_info.radio_freq)
1573 + l1ps.last_PR_good;
1574
1575 // IL_2_AGC_xx array size
1576 if (input_level>INDEX_MAX) input_level = INDEX_MAX;
1577
1578 // lna_off processing
1579 new_calibrated_IL = (WORD16) (input_level - l1ctl_encode_delta1(l1ps.read_param.radio_freq_for_lna));
1580
1581 if (new_calibrated_IL>INDEX_MAX) new_calibrated_IL = INDEX_MAX;
1582
1583 l1ctl_encode_lna((UWORD8)(new_calibrated_IL>>1), &(l1a_l1s_com.Scell_info.transfer_meas.lna_off), l1ps.read_param.radio_freq_for_lna);
1584
1585 l1a_l1s_com.Scell_info.transfer_meas.input_level = input_level +
1586 l1a_l1s_com.Scell_info.transfer_meas.lna_off *
1587 l1ctl_get_lna_att(l1ps.read_param.radio_freq_for_lna);
1588
1589 } // End if "burst = 3"
1590
1591 } // End of "l1pctl_dpcmb_agc_read"
1592
1593 /*-------------------------------------------------------*/
1594 /* l1pctl_pgc() */
1595 /*-------------------------------------------------------*/
1596 /* Description : */
1597 /* ============= */
1598 /* This function is used in packet transfer mode for the*/
1599 /* Read phase of power measurements. It permits to: */
1600 /* - Process the IL value in function of the Pm and AGC */
1601 /* used */
1602 /* - Update the FIFO[beacon] used in packet transfer AGC*/
1603 /* algorithms */
1604 /* - Update last_input_level */
1605 /* */
1606 /* WARNING: in the layer 1 code, input levels IL(l1) use */
1607 /* format 7.1: */
1608 /* ********************* */
1609 /* * IL(l1) = - 2 x IL * */
1610 /* ********************* */
1611 /* -> Reversed sign, reversed test conditions */
1612 /* -> max replaced by min */
1613 /* ex: if IL -120 dBm, IL(l1) = 240 */
1614 /*-------------------------------------------------------*/
1615 UWORD8 l1pctl_pgc(UWORD8 pm, UWORD8 last_known_il, UWORD8 lna_off, UWORD16 radio_freq)
1616 {
1617 UWORD8 i, new_IL;
1618 WORD8 delta1_freq, delta2_freq;
1619 WORD16 delta_drp_gain=0;
1620 UWORD16 lna_value;
1621 WORD16 used_agc, current_IL, current_calibrated_IL, new_calibrated_IL;
1622 WORD32 index;
1623 #if (RF_FAM == 61)
1624 UWORD16 arfcn;
1625 #endif
1626 UWORD16 dco_algo_ctl_pw_temp = 0;
1627 UWORD8 if_ctl = 0;
1628 #if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
1629 UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GPRS;
1630 #endif
1631
1632 // Calibration factors
1633 delta1_freq = l1ctl_encode_delta1(radio_freq);
1634 delta2_freq = l1ctl_encode_delta2(radio_freq);
1635
1636 // initialize index
1637 #if(L1_FF_MULTIBAND == 0)
1638 index = radio_freq - l1_config.std.radio_freq_index_offset;
1639
1640 #else
1641 index = l1_multiband_radio_freq_convert_into_operative_radio_freq(radio_freq);
1642 #endif
1643
1644
1645 // LNA attenuation
1646 lna_value = lna_off * l1ctl_get_lna_att(radio_freq);
1647
1648 // Used AGC in the control phase (format F7.1)
1649 used_agc = (Cust_get_agc_from_IL(radio_freq, last_known_il >> 1, PWR_ID)) << 1;
1650
1651
1652 #if (RF_FAM == 61)
1653 // DRP correction
1654 #if (L1_FF_MULTIBAND == 0)
1655 arfcn = Convert_l1_radio_freq(radio_freq);
1656 #else
1657 arfcn=radio_freq;
1658 #endif
1659
1660 #if (CODE_VERSION != SIMULATION)
1661
1662
1663 #if (PWMEAS_IF_MODE_FORCE == 0)
1664 cust_get_if_dco_ctl_algo(&dco_algo_ctl_pw_temp, &if_ctl, (UWORD8) L1_IL_VALID ,
1665 last_known_il,
1666 radio_freq, if_threshold);
1667 #else
1668 if_ctl = IF_120KHZ_DSP;
1669 dco_algo_ctl_pw_temp = DCO_IF_0KHZ;
1670 #endif
1671
1672 lna_off = l1a_l1s_com.Scell_used_IL_dd.lna_off;
1673 delta_drp_gain = drp_gain_correction(arfcn, lna_off, used_agc); // F7.1 format
1674
1675 if(if_ctl == IF_100KHZ_DSP){
1676 delta_drp_gain += SCF_ATTENUATION_LIF_100KHZ;
1677 }
1678 else{ /* i.e. if_ctl = IF_120KHZ_DSP*/
1679 delta_drp_gain += SCF_ATTENUATION_LIF_120KHZ;
1680 }
1681
1682
1683 #endif
1684 #endif
1685
1686 if (0==pm) // Check and filter illegal pm value by using last valid IL
1687 current_IL = l1a_l1s_com.last_input_level[index].input_level - lna_value;
1688 else
1689 current_IL = -(pm - (used_agc - delta_drp_gain) + lna_value - l1ctl_get_g_magic(radio_freq));
1690
1691 // Calibrated IL processing
1692 current_calibrated_IL = current_IL - delta1_freq - delta2_freq;
1693
1694 // Protect IL stores against overflow
1695 if (current_calibrated_IL>INDEX_MAX)
1696 current_calibrated_IL=INDEX_MAX;
1697 if (current_IL>INDEX_MAX)
1698 current_IL=INDEX_MAX;
1699
1700 // if radio freq is the serving beacon
1701 //------------------------------------
1702 if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
1703 {
1704 // FIFO management
1705 for (i=3;i>0;i--)
1706 l1a_l1s_com.Scell_info.buff_beacon[i] = l1a_l1s_com.Scell_info.buff_beacon[i-1];
1707 l1a_l1s_com.Scell_info.buff_beacon[0] = (UWORD8) current_IL;
1708
1709 // Find min IL in FIFO
1710 new_IL = l1ctl_find_max(l1a_l1s_com.Scell_info.buff_beacon,4);
1711
1712 // lna_off processing
1713 new_calibrated_IL = (WORD16) (new_IL - delta1_freq - delta2_freq);
1714 if (new_calibrated_IL>INDEX_MAX) new_calibrated_IL = INDEX_MAX;
1715
1716 l1ctl_encode_lna((UWORD8)(new_calibrated_IL>>1),
1717 &(l1a_l1s_com.last_input_level[index].lna_off),
1718 radio_freq);
1719
1720 l1a_l1s_com.last_input_level[index].input_level = new_IL +
1721 l1a_l1s_com.last_input_level[index].lna_off *
1722 l1ctl_get_lna_att(radio_freq);
1723 }
1724
1725 // if radio freq is a neighbor beacon
1726 //-----------------------------------
1727 else
1728 {
1729 // Update last_input_level (IL with LNA ON)
1730 l1ctl_encode_lna((UWORD8)(current_calibrated_IL>>1),
1731 &(l1a_l1s_com.last_input_level[index].lna_off),
1732 radio_freq);
1733
1734 l1a_l1s_com.last_input_level[index].input_level = current_IL +
1735 l1a_l1s_com.last_input_level[index].lna_off *
1736 l1ctl_get_lna_att(radio_freq);
1737 }
1738
1739 return((UWORD8)current_calibrated_IL);
1740
1741 } // End of "l1pctl_pgc"
1742 #endif