FreeCalypso > hg > fc-magnetite
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 |