comparison src/cs/layer1/p_cfile/l1p_sync.c @ 0:b6a5e36de839

src/cs: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:39:26 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:b6a5e36de839
1 /************* Revision Controle System Header *************
2 * GSM Layer 1 software
3 * L1P_SYNC.C
4 *
5 * Filename l1p_sync.c
6 * Copyright 2003 (C) Texas Instruments
7 *
8 ************* Revision Controle System Header *************/
9
10 #define L1P_SYNC_C
11
12 //#pragma DUPLICATE_FOR_INTERNAL_RAM_START
13
14 #include "l1_macro.h"
15 #include "l1_confg.h"
16
17 #if L1_GPRS
18
19 #if (CODE_VERSION == SIMULATION)
20 #include <string.h>
21 #include "l1_types.h"
22 #include "sys_types.h"
23 #include "l1_const.h"
24 #include "l1_time.h"
25 #include <l1_trace.h>
26 #if TESTMODE
27 #include "l1tm_defty.h"
28 #endif
29 #if (AUDIO_TASK == 1)
30 #include "l1audio_const.h"
31 #include "l1audio_cust.h"
32 #include "l1audio_defty.h"
33 #endif
34 #if (L1_GTT == 1)
35 #include "l1gtt_const.h"
36 #include "l1gtt_defty.h"
37 #endif
38 #if (L1_MP3 == 1)
39 #include "l1mp3_defty.h"
40 #endif
41 #if (L1_MIDI == 1)
42 #include "l1midi_defty.h"
43 #endif
44 #include "l1_defty.h"
45 #include "cust_os.h"
46 #include "l1_msgty.h"
47 #include "l1_varex.h"
48 #include "l1_signa.h"
49 #include "l1_proto.h"
50
51 #if L2_L3_SIMUL
52 #include "hw_debug.h"
53 #endif
54
55 #include "l1p_cons.h"
56 #include "l1p_msgt.h"
57 #include "l1p_deft.h"
58 #include "l1p_vare.h"
59 #include "l1p_prot.h"
60 #include "l1p_mfta.h"
61 #include "l1p_sign.h"
62 #include "l1p_macr.h"
63 #include "l1p_proto.h"
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
71 #if TESTMODE
72 #include "l1tm_defty.h"
73 #endif
74 #if (AUDIO_TASK == 1)
75 #include "l1audio_const.h"
76 #include "l1audio_cust.h"
77 #include "l1audio_defty.h"
78 #endif
79 #if (L1_GTT == 1)
80 #include "l1gtt_const.h"
81 #include "l1gtt_defty.h"
82 #endif
83 #if (L1_MP3 == 1)
84 #include "l1mp3_defty.h"
85 #endif
86 #if (L1_MIDI == 1)
87 #include "l1midi_defty.h"
88 #endif
89 #include "l1_defty.h"
90 #include "cust_os.h"
91 #include "l1_msgty.h"
92 #include "l1_varex.h"
93 #include "l1_signa.h"
94 #include "l1_proto.h"
95 #include "l1_trace.h"
96
97 #if L2_L3_SIMUL
98 #include "hw_debug.h"
99 #endif
100
101 #include "l1p_cons.h"
102 #include "l1p_msgt.h"
103 #include "l1p_deft.h"
104 #include "l1p_vare.h"
105 #include "l1p_prot.h"
106 #include "l1p_mfta.h"
107 #include "l1p_sign.h"
108 #include "l1p_macr.h"
109 #endif
110
111 #if(RF_FAM == 61)
112 #include "l1_rf61.h"
113 #include "tpudrv61.h"
114 #endif
115
116 #if (GSM_IDLE_RAM !=0)
117 #if (OP_L1_STANDALONE == 0)
118 #include "csmi/sleep.h"
119 #else
120 #include "csmi_simul.h"
121 #endif
122 #endif
123
124 /*-------------------------------------------------------*/
125 /* Prototypes of external functions used in this file. */
126 /*-------------------------------------------------------*/
127 void l1ps_tcr_ctrl (UWORD8 pm_position);
128 void l1pddsp_meas_ctrl (UWORD8 nbmeas, UWORD8 pm_pos);
129 void l1pddsp_meas_read (UWORD8 nbmeas, UWORD8 *pm_read);
130 void l1pctl_transfer_agc_init();
131 UWORD8 l1pctl_pgc (UWORD8 pm, UWORD8 last_known_il, UWORD8 lna_off, UWORD16 radio_freq);
132 void l1ps_bcch_meas_ctrl (UWORD8 ts);
133
134 //#pragma DUPLICATE_FOR_INTERNAL_RAM_END
135
136
137 #if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
138 //#pragma DUPLICATE_FOR_INTERNAL_RAM_START
139
140 /*-------------------------------------------------------*/
141 /* l1ps_transfer_mode_manager() */
142 /*-------------------------------------------------------*/
143 /* Parameters : */
144 /* Return : */
145 /* Functionality : */
146 /*-------------------------------------------------------*/
147 void l1ps_transfer_mode_manager()
148 {
149 BOOL block_boundary = TRUE;
150 UWORD8 current_assignment_command = NO_TBF;
151 #if FF_TBF
152 BOOL tbf_update_synchro_forced = FALSE;
153 #endif
154
155 //====================================
156 // NEW configuration management
157 //====================================
158
159 if(!l1pa_l1ps_com.transfer.semaphore)
160 // IF Transfer parameter structure protected,
161 // No action within L1S.
162 {
163 WORD8 i;
164 UWORD8 min_synchro_ts = 7;
165 BOOL new_tbf_installed = FALSE;
166 T_PACKET_TA *current_ta_config;
167
168 // In packet transfer mode, we only detect STI at block boundaries in order to udpate the
169 // ASET structure after the last Control of the previous TBF
170 if (l1a_l1s_com.l1s_en_task[PDTCH] == TASK_ENABLED)
171 {
172 if ((l1s.next_time.fn_mod13 != 0)&&(l1s.next_time.fn_mod13 != 4)&&
173 (l1s.next_time.fn_mod13 != 8))
174 {
175 block_boundary = FALSE;
176 }
177 }
178 // Delay STI detection when a poll response hasn't already been answered
179 // for transition to Packet transfer mode
180 else if (l1a_l1s_com.l1s_en_task[POLL] == TASK_ENABLED)
181 {
182 block_boundary = FALSE;
183 }
184
185 // LOOK FOR NEW ASSIGNMENT...
186 //===========================
187
188 // Consider both FREE SET...
189 for(i=0;i<2;i++)
190 {
191 // Is there a new transfer channel provided in "fset[i]"?
192 if(((l1pa_l1ps_com.transfer.fset[i]->SignalCode == MPHP_ASSIGNMENT_REQ) && (block_boundary == TRUE)) ||
193 (l1pa_l1ps_com.transfer.fset[i]->SignalCode == MPHP_SINGLE_BLOCK_REQ))
194 {
195 if(l1pa_l1ps_com.transfer.fset[i]->tbf_sti.present)
196 // Starting time present.
197 // Rem: starting time detected 1 frame in advance, this frame is used by
198 // SYNCHRO task.
199 {
200 WORD32 time_diff;
201 WORD8 frame_shift=0;
202 WORD8 tn_diff;
203
204
205 // In packet idle mode, L1 must detect if the synchronization change will happen
206 // from a timeslot N to a timeslot M < N because in this case, a frame is skipped
207 // and the MS is ready two frames after the synchronization change... a radio
208 // block can be missed...
209 // In packet transfer, the SYNCHRO task will always been executed on BURST 1, that let
210 // 2 frames before the new TBF starts
211 if (l1a_l1s_com.l1s_en_task[PDTCH] != TASK_ENABLED)
212 {
213 frame_shift -= 1;
214
215 tn_diff = l1pa_l1ps_com.transfer.fset[i]->transfer_synchro_timeslot -
216 l1a_l1s_com.dl_tn;
217
218 if(tn_diff < 0)
219 frame_shift -= 1;
220 }
221 //TBF_changes
222
223 #if FF_TBF
224 // PDTCH task is enabled
225 else
226 {
227 // Pseudo TBF for Two phase access, new TBF configuration has to
228 // be installed for Starting Time taking into account that a
229 // SYNCHRO task has to be scheduled before.
230 if ((l1pa_l1ps_com.transfer.aset->allocated_tbf == UL_TBF) &&
231 (l1pa_l1ps_com.transfer.aset->pseudo_tbf_two_phase_acc))
232 {
233 // Note: We are at block boundary.
234 if ((l1s.next_time.fn_mod13 == 0) || (l1s.next_time.fn_mod13 == 4))
235 frame_shift -= 4;
236 else // i.e. (l1s.next_time.fn_mod13 == 8)
237 frame_shift -= 5;
238 }
239
240 // Two phase access establishment on PACCH (therefore there is an
241 // ongoing uplink TBF).
242 if ((l1pa_l1ps_com.transfer.fset[i]->allocated_tbf == UL_TBF) &&
243 (l1pa_l1ps_com.transfer.fset[i]->pseudo_tbf_two_phase_acc))
244 {
245 // Make sure single/multi block allocation
246 // if a synchro task has to be inserted i.e. :
247 // -> we are currently in EGPRS mode
248 // -> and/or we change synchronization timeslot
249 if ( (l1pa_l1ps_com.transfer.fset[i]->transfer_synchro_timeslot != l1a_l1s_com.dl_tn)
250 #if L1_EGPRS
251 || (l1pa_l1ps_com.transfer.aset->egprs_param.tbf_mode == TBF_MODE_EGPRS)
252 #endif
253 )
254 {
255 // Note: We are at block boundary.
256 if ((l1s.next_time.fn_mod13 == 0) || (l1s.next_time.fn_mod13 == 4))
257 frame_shift -= 4;
258 else // i.e. (l1s.next_time.fn_mod13 == 8)
259 frame_shift -= 5;
260 }
261 }
262 }
263 #endif
264
265
266 time_diff = ( (l1pa_l1ps_com.transfer.fset[i]->tbf_sti.absolute_fn) +
267 frame_shift - (l1s.next_time.fn % 42432) + 2*42432) % 42432;
268
269 if((time_diff >= (32024)) && (time_diff <= (42431)))
270 // Starting time has been passed...
271 //---------------------------------
272 {
273 // For SINGLE BLOCK case, an error must be reported to L3.
274 if(l1pa_l1ps_com.transfer.fset[i]->SignalCode == MPHP_SINGLE_BLOCK_REQ)
275 {
276 xSignalHeaderRec *msg;
277
278 // Send confirmation msg to L3/MACA.
279 msg = os_alloc_sig(sizeof(T_MPHP_SINGLE_BLOCK_CON));
280 DEBUGMSG(status,NU_ALLOC_ERR)
281
282 ((T_MPHP_SINGLE_BLOCK_CON *)(msg->SigP))->purpose =
283 l1pa_l1ps_com.transfer.fset[i]->assignment_command;
284 ((T_MPHP_SINGLE_BLOCK_CON *)(msg->SigP))->assignment_id =
285 l1pa_l1ps_com.transfer.fset[i]->assignment_id;
286
287 ((T_MPHP_SINGLE_BLOCK_CON *)(msg->SigP))->status = SINGLE_STI_PASSED;
288
289 msg->SignalCode = L1P_SINGLE_BLOCK_CON;
290
291 // send message...
292 os_send_sig(msg, L1C1_QUEUE);
293 DEBUGMSG(status,NU_SEND_QUEUE_ERR)
294
295 // Do not reset "tbf_sti.present".
296
297 // Ignore the SINGLE BLOCK requested.
298 l1pa_l1ps_com.transfer.fset[i]->SignalCode = NULL;
299 }
300 else
301 {
302 // Reset "tbf_sti.present" flag to take into account the new
303 // configuration.
304 l1pa_l1ps_com.transfer.fset[i]->tbf_sti.present = FALSE;
305 }
306 }
307 else
308 if(time_diff == 0)
309 // Starting time corresponds to current frame...
310 //----------------------------------------------
311 {
312 // Reset "tbf_sti.present" flag to take into account the new
313 // configuration.
314 l1pa_l1ps_com.transfer.fset[i]->tbf_sti.present = FALSE;
315 }
316 else
317 // Starting time hasn't already been reached...
318 //---------------------------------------------
319 {
320 // time_to_next_l1s_task updated with time to sti
321 Select_min_time(time_diff, l1a_l1s_com.time_to_next_l1s_task);
322 }
323 }
324
325 // Do we switch to a new transfer configuration?
326 // We have to switch if, new set STI is passed.
327 if(!l1pa_l1ps_com.transfer.fset[i]->tbf_sti.present)
328 {
329 // Install new configuration immediately.
330 // Rem: the new channel will start at a block boundary because by construction
331 // PDTCH task is started every block boundary.
332 T_TRANSFER_SET *transfer_set;
333
334 // STI has been passed, we must switch to the new config.
335
336 #if (TRACE_TYPE!=0)
337 // Trace "starting time" on log file and screen.
338 trace_fct(CST_STI_PASSED, l1a_l1s_com.Scell_info.radio_freq);
339 #endif
340
341 #if FF_TBF
342 // Forces a SYNCHRO task prior to new TBF configuration if
343 // -> Coming from 2 phases access TBF
344 // -> Coming from (Packet) Idle
345 if (((l1pa_l1ps_com.transfer.aset->allocated_tbf == UL_TBF) &&
346 (l1pa_l1ps_com.transfer.aset->pseudo_tbf_two_phase_acc))
347 || (l1a_l1s_com.l1s_en_task[PDTCH] == TASK_DISABLED)
348 )
349 {
350 // Can not be merged with test above evaluated only when a
351 // starting time is present in the message.
352 tbf_update_synchro_forced = TRUE;
353 }
354 #endif
355 if (current_assignment_command == NO_TBF)
356 current_assignment_command = l1pa_l1ps_com.transfer.fset[i]->assignment_command;
357 else if ((current_assignment_command == UL_TBF) ||
358 (current_assignment_command == DL_TBF))
359 current_assignment_command = BOTH_TBF;
360
361 // Check if anything to keep from previous configuration.
362 // Select the best timeslot for timebase synchro.
363
364 if(l1pa_l1ps_com.transfer.aset->allocated_tbf != NO_TBF)
365 {
366 UWORD8 synchro_ts;
367
368 // Check if required to take TA from previous packet assignment
369 // if TA not valid in new assignment command
370 if ( l1pa_l1ps_com.transfer.fset[i]->packet_ta.ta == 255)
371 {
372 // new TA value to be taken from previous packet TA
373 l1pa_l1ps_com.transfer.fset[i]->packet_ta.ta = l1pa_l1ps_com.transfer.aset->packet_ta.ta;
374 }
375
376 switch(l1pa_l1ps_com.transfer.fset[i]->assignment_command)
377 {
378 case DL_TBF:
379 {
380 // If any, keep the UL allocation from previous set.
381 if((l1pa_l1ps_com.transfer.aset->allocated_tbf == UL_TBF) ||
382 (l1pa_l1ps_com.transfer.aset->allocated_tbf == BOTH_TBF))
383 {
384 T_UL_RESSOURCE_ALLOC *ul_ptr;
385
386 // Swap the pointers on UL parameter structures
387 ul_ptr = l1pa_l1ps_com.transfer.fset[i]->ul_tbf_alloc;
388 l1pa_l1ps_com.transfer.fset[i]->ul_tbf_alloc =
389 l1pa_l1ps_com.transfer.aset->ul_tbf_alloc;
390 l1pa_l1ps_com.transfer.aset->ul_tbf_alloc = ul_ptr;
391
392 l1pa_l1ps_com.transfer.fset[i]->allocated_tbf = BOTH_TBF;
393 l1pa_l1ps_com.transfer.fset[i]->ul_tbf_synchro_timeslot =
394 l1pa_l1ps_com.transfer.aset->ul_tbf_synchro_timeslot;
395
396 // Chose min synchro timeslot from UL and DL TBFs.
397 if(l1pa_l1ps_com.transfer.aset->ul_tbf_synchro_timeslot <
398 l1pa_l1ps_com.transfer.fset[i]->transfer_synchro_timeslot)
399 {
400 synchro_ts = l1pa_l1ps_com.transfer.aset->ul_tbf_synchro_timeslot;
401 }
402 else
403 {
404 synchro_ts = l1pa_l1ps_com.transfer.fset[i]->transfer_synchro_timeslot;
405 }
406 }
407
408 // No UL TBF running, select the new DL TBF synchro timeslot.
409 else
410 {
411 synchro_ts = l1pa_l1ps_com.transfer.fset[i]->transfer_synchro_timeslot;
412 }
413 }
414 break;
415
416 case UL_TBF:
417 {
418 // If any, keep the DL allocation from previous set.
419
420 if((l1pa_l1ps_com.transfer.aset->allocated_tbf == DL_TBF) ||
421 (l1pa_l1ps_com.transfer.aset->allocated_tbf == BOTH_TBF))
422 {
423 l1pa_l1ps_com.transfer.fset[i]->dl_tbf_alloc =
424 l1pa_l1ps_com.transfer.aset->dl_tbf_alloc;
425 l1pa_l1ps_com.transfer.fset[i]->allocated_tbf = BOTH_TBF;
426 l1pa_l1ps_com.transfer.fset[i]->dl_tbf_synchro_timeslot =
427 l1pa_l1ps_com.transfer.aset->dl_tbf_synchro_timeslot;
428
429 // Chose min synchro timeslot from UL and DL TBFs.
430 if(l1pa_l1ps_com.transfer.aset->dl_tbf_synchro_timeslot <
431 l1pa_l1ps_com.transfer.fset[i]->transfer_synchro_timeslot)
432 {
433 synchro_ts = l1pa_l1ps_com.transfer.aset->dl_tbf_synchro_timeslot;
434 }
435 else
436 {
437 synchro_ts = l1pa_l1ps_com.transfer.fset[i]->transfer_synchro_timeslot;
438 }
439 }
440
441 // No DL TBF running, select the new UL TBF synchro timeslot.
442 else
443 {
444 synchro_ts = l1pa_l1ps_com.transfer.fset[i]->transfer_synchro_timeslot;
445 }
446
447 // Reset Repeat allocation starting time checking
448 l1pa_l1ps_com.transfer.repeat_alloc.repeat_allocation = FALSE;
449 // Reset Allocation Exhaustion detection flag
450 l1ps_macs_com.fix_alloc_exhaust_flag = FALSE;
451 }
452 break;
453
454 case BOTH_TBF:
455 case NO_TBF:
456 default:
457 {
458 // Nothing to keep, everything (UL & DL) is replaced.
459 synchro_ts = l1pa_l1ps_com.transfer.fset[i]->transfer_synchro_timeslot;
460
461 // Reset Repeat allocation starting time checking
462 l1pa_l1ps_com.transfer.repeat_alloc.repeat_allocation = FALSE;
463 // Reset Allocation Exhaustion detection flag
464 l1ps_macs_com.fix_alloc_exhaust_flag = FALSE;
465 }
466 break;
467
468 } // end of switch(...assignment_command)
469
470 if(synchro_ts < min_synchro_ts)
471 min_synchro_ts = synchro_ts;
472
473 } // end of if(...allocated_tbf != NO_TBF)
474
475 else
476 {
477 min_synchro_ts = l1pa_l1ps_com.transfer.fset[i]->transfer_synchro_timeslot;
478 }
479
480 // New set becomes active and old becomes free.
481
482 // Save a pointer on currently used PTCCH parameters
483 current_ta_config = &l1pa_l1ps_com.transfer.aset->packet_ta;
484
485 transfer_set = l1pa_l1ps_com.transfer.aset;
486 l1pa_l1ps_com.transfer.aset = l1pa_l1ps_com.transfer.fset[i];
487 l1pa_l1ps_com.transfer.fset[i] = transfer_set;
488 l1pa_l1ps_com.transfer.fset[i]->allocated_tbf = NO_TBF;
489
490 l1pa_l1ps_com.transfer.aset->transfer_synchro_timeslot = min_synchro_ts;
491
492 // Set local flag.
493 new_tbf_installed = TRUE;
494
495 if(l1pa_l1ps_com.transfer.aset->SignalCode == MPHP_ASSIGNMENT_REQ)
496 // Assignement confirmation message is sent
497 {
498 xSignalHeaderRec *msg;
499
500 // Send confirmation msg to L3/MACA.
501 msg = os_alloc_sig(sizeof(T_L1P_TRANSFER_DONE));
502 DEBUGMSG(status,NU_ALLOC_ERR)
503
504 msg->SignalCode = L1P_TRANSFER_DONE;
505
506 ((T_L1P_TRANSFER_DONE *) (msg->SigP))->assignment_id =
507 l1pa_l1ps_com.transfer.aset->assignment_id;
508
509 // Insert "t_difference" information in L1P_TRANSFER_DONE msg
510 // will be used in Ncell Dedic6 state machine to request a reset
511 // or not of the state machine
512 ((T_L1P_TRANSFER_DONE *) (msg->SigP))->tn_difference =
513 min_synchro_ts - l1a_l1s_com.dl_tn;
514
515
516 // detect the Transition IDLE -> Transfer
517 if (l1a_l1s_com.l1s_en_task[PDTCH] == TASK_ENABLED)
518 ((T_L1P_TRANSFER_DONE *) (msg->SigP))->Transfer_update = TRUE;
519 else
520 ((T_L1P_TRANSFER_DONE *) (msg->SigP))->Transfer_update = FALSE;
521
522
523 os_send_sig(msg, L1C1_QUEUE);
524 DEBUGMSG(status,NU_SEND_QUEUE_ERR)
525 }
526
527 // New config has been acknowledeged, clear SignalCode...
528 l1pa_l1ps_com.transfer.fset[i]->SignalCode = NULL;
529 l1pa_l1ps_com.transfer.aset->SignalCode = NULL;
530
531 } // end if(...tbf_sti.present)
532 } // end of if(...SignalCode == MPHP_ASSIGNMENT_REQ)
533 }
534
535 if(new_tbf_installed == TRUE)
536 {
537 // Start the new configuration
538 //----------------------------
539
540 // Enable PACKET tasks.
541 {
542 // Set assignment_command to the last enabled TBF type.
543 // This permits MAC-S to correctly manage TBF boundary conditions.
544 l1pa_l1ps_com.transfer.aset->assignment_command = current_assignment_command;
545
546 // Flag the new configuration to MACS.
547 l1ps_macs_com.new_set = TRUE;
548
549 // Flag the new configuration in order to update the Read set parameters
550 // in the first Read phase of the new TBF
551 // This permits to start using the new aset parameters for the first Control of
552 // the first block of the new TBF and to keep the parameters needed for the
553 // last read phase of the last block of the previous TBF.
554 l1ps.read_param.new_set = TRUE;
555
556 // TBF_changes
557 #if !FF_TBF
558 // We need to detect that we just leaving CS/P Idle mode to enter
559 // in Packet Transfer mode. Then we have to enable SYNCHRO task on dectection
560 // of a mode change (Idle or Packet idle -> Packet transfer).
561 // Note: This check can't be gathered with the one done a little bit later
562 // on tn_difference and SINGLE task from the fact that the allocated_tbf
563 // is checked and PDTCH enabled.
564 if(l1a_l1s_com.task_param[SYNCHRO] == SEMAPHORE_RESET)
565 {
566 if(l1a_l1s_com.l1s_en_task[PDTCH] == TASK_DISABLED)
567 {
568 l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;
569 l1a_l1s_com.dsp_scheduler_mode = GPRS_SCHEDULER;
570 }
571 }
572 #endif
573
574 // Disable interference measurements
575 l1a_l1s_com.l1s_en_task[ITMEAS] = TASK_DISABLED;
576
577 // Check for Continuous Timing advance procedure.
578 // Enable PTCCH task if required.
579 if((l1pa_l1ps_com.transfer.aset->packet_ta.ta_index != 255) &&
580 (l1pa_l1ps_com.transfer.aset->packet_ta.ta_tn != 255))
581 {
582 // No action when the configuration is the same as the current one.
583 if((l1pa_l1ps_com.transfer.aset->packet_ta.ta_index != current_ta_config->ta_index) ||
584 (l1pa_l1ps_com.transfer.aset->packet_ta.ta_tn != current_ta_config->ta_tn) ||
585 (l1a_l1s_com.l1s_en_task[PTCCH] == TASK_DISABLED))
586 // The configuration is different than the current one or no PTCCH is currently running
587 // (for example in packet idle)
588 {
589 // Reset PTCCH execution variables.
590 l1pa_l1ps_com.transfer.ptcch.activity = 0;
591 l1pa_l1ps_com.transfer.ptcch.request_dl = FALSE;
592
593 // Enable PTCCH task.
594 l1a_l1s_com.l1s_en_task[PTCCH] = TASK_ENABLED;
595 }
596 }
597 else
598 // PTCCH is not configured.
599 {
600 // Disable PTCCH task.
601 l1a_l1s_com.l1s_en_task[PTCCH] = TASK_DISABLED;
602 }
603
604 // Transfer AGC initialization
605 l1pctl_transfer_agc_init();
606
607 switch(l1pa_l1ps_com.transfer.aset->allocated_tbf)
608 {
609 case SINGLE_BLOCK_UL:
610 {
611 // Set SINGLE execution variables.
612 l1pa_l1ps_com.transfer.single_block.activity = SINGLE_UL; // UL enabled
613
614 // Enable SINGLE task.
615 l1a_l1s_com.l1s_en_task[SINGLE] = TASK_ENABLED;
616 }
617 break;
618
619 case SINGLE_BLOCK_DL:
620 {
621 // Set SINGLE execution variables.
622 l1pa_l1ps_com.transfer.single_block.activity = SINGLE_DL; // DL enabled
623
624 // Enable SINGLE task.
625 l1a_l1s_com.l1s_en_task[SINGLE] = TASK_ENABLED;
626 }
627 break;
628
629 case TWO_PHASE_ACCESS:
630 {
631 // Set SINGLE execution variables.
632 l1pa_l1ps_com.transfer.single_block.activity |= SINGLE_DL; // DL enabled
633 l1pa_l1ps_com.transfer.single_block.activity |= SINGLE_UL; // UL enabled
634
635 // Enable SINGLE task.
636 l1a_l1s_com.l1s_en_task[SINGLE] = TASK_ENABLED;
637 }
638 break;
639
640 default:
641 {
642 /*
643 * FreeCalypso: removal of the following line is
644 * TCS211 reconstruction
645 */
646 //if(l1a_l1s_com.l1s_en_task[PDTCH] == TASK_ENABLED)
647 //In case of transition idle to transfer the Packet transfer mode is set when synchro is executed
648 // Layer 1 internal mode is set to PACKET TRANSFER MODE.
649 l1a_l1s_com.mode = PACKET_TRANSFER_MODE;
650
651 // Enable PDTCH task.
652 l1a_l1s_com.l1s_en_task[PDTCH] = TASK_ENABLED;
653
654 // Need to disable SINGLE task for two phase access case
655 l1a_l1s_com.l1s_en_task[SINGLE] = TASK_DISABLED;
656 }
657 break;
658 } // End switch()
659
660 // SYNCHRO task is not schedule if we are in the specific case:
661 // L1A is touching SYNCHRO parameters (tn_difference, dl_tn and dsp_scheduler_mode)
662 // and leave L1A to go in HISR (L1S) in middle of the update (cf. BUG1339)
663 // Note: tn_difference has to be accumulated in order to cope with the
664 // specific case: L1A has just updated tn_difference, dl_tn and dsp_scheduler_mode
665 // parameters and we enter in the HISR after the reset of the SYNCHRO Semaphore.
666 if(l1a_l1s_com.task_param[SYNCHRO] == SEMAPHORE_RESET)
667 {
668 // Save the "timeslot difference" between new and old configuration
669 // in "tn_difference".
670 // tn_difference -> loaded with the number of timeslot to shift.
671 // dl_tn -> loaded with the new timeslot.
672 l1a_l1s_com.tn_difference += min_synchro_ts - l1a_l1s_com.dl_tn;
673 l1a_l1s_com.dl_tn = min_synchro_ts;
674
675 #if !FF_TBF
676 // Enable SYNCHRO task only if lowest allocated timeslot changed
677 // or if each time the SINGLE task is enabled
678 // In the specific case of the SINGLE task, the GPRS_SCHEDULER
679 // has to be selected.
680 if((l1a_l1s_com.tn_difference != 0) ||
681 (l1a_l1s_com.l1s_en_task[SINGLE] == TASK_ENABLED))
682 {
683 l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;
684 l1a_l1s_com.dsp_scheduler_mode = GPRS_SCHEDULER;
685 }
686 #else
687 // Enable SYNCHRO task if at least one of these conditions fulfilled:
688 // -> Change in the timeslot synhronization
689 // -> Change of the ongoing TBF mode (synchro_forced)
690 // -> Exit of two phase access (synchro_forced)
691 // -> Coming from (Packet) Idle (synchro forced)
692 // -> SINGLE task enabled
693 if((l1a_l1s_com.tn_difference != 0) ||
694 (tbf_update_synchro_forced) ||
695 (l1a_l1s_com.l1s_en_task[SINGLE] == TASK_ENABLED))
696 {
697 l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;
698
699 l1a_l1s_com.dsp_scheduler_mode = GPRS_SCHEDULER;
700 }
701 #endif
702 }
703 else
704 {}// L1A is touching dl_tn, tn_difference and dsp_scheduler_mode parameters...
705 }
706 }
707
708 // LOOK FOR TIMING AVANCE UPDATE
709 //===============================
710
711 if(l1pa_l1ps_com.transfer.ptcch.ta_update_cmd == TRUE)
712 {
713 #define CURRENT_TA_CONFIG l1pa_l1ps_com.transfer.aset->packet_ta
714 #define NEW_TA_CONFIG l1pa_l1ps_com.transfer.ptcch.packet_ta
715
716 // Only update if the assignment_id of the running TBF matches with the assignment_id
717 // given in the MPHP_TIMING_ADVANCE_REQ message
718 if (l1pa_l1ps_com.transfer.ptcch.assignment_id == l1pa_l1ps_com.transfer.aset->assignment_id)
719 {
720 xSignalHeaderRec *msg;
721
722 // Immediate Update of PACKET TA structure.
723 //-----------------------------------------
724
725 // Update TA value only if a new value is provided.
726 if(NEW_TA_CONFIG.ta != 255)
727 CURRENT_TA_CONFIG.ta = NEW_TA_CONFIG.ta;
728
729 if((NEW_TA_CONFIG.ta_index != 255) &&
730 (NEW_TA_CONFIG.ta_tn != 255))
731 // There is a New PTCCH configuration.
732 {
733 // No action when the configuration is the same as the current one.
734
735 if((NEW_TA_CONFIG.ta_index != CURRENT_TA_CONFIG.ta_index) ||
736 (NEW_TA_CONFIG.ta_tn != CURRENT_TA_CONFIG.ta_tn))
737 // The configuration is different than the current one.
738 {
739 // Download the new configuration.
740 CURRENT_TA_CONFIG.ta_index = NEW_TA_CONFIG.ta_index;
741 CURRENT_TA_CONFIG.ta_tn = NEW_TA_CONFIG.ta_tn;
742
743 // Reset PTCCH execution variables.
744 l1pa_l1ps_com.transfer.ptcch.activity = 0;
745 l1pa_l1ps_com.transfer.ptcch.request_dl = FALSE;
746
747 // Enable PTCCH task.
748 l1a_l1s_com.l1s_en_task[PTCCH] = TASK_ENABLED;
749 }
750 }
751 else
752 // PTCCH is not configured.
753 {
754 // Diable PTCCH task.
755 l1a_l1s_com.l1s_en_task[PTCCH] = TASK_DISABLED;
756 }
757
758 // Send confirmation message to L3.
759 msg = os_alloc_sig(sizeof(T_MPHP_TIMING_ADVANCE_CON));
760 DEBUGMSG(status,NU_ALLOC_ERR)
761
762 msg->SignalCode = L1P_TA_CONFIG_DONE;
763 ((T_MPHP_TIMING_ADVANCE_CON *) msg->SigP)->assignment_id =
764 l1pa_l1ps_com.transfer.aset->assignment_id;
765
766 os_send_sig(msg, L1C1_QUEUE);
767 DEBUGMSG(status,NU_SEND_QUEUE_ERR)
768
769 } // End if "assignment_id of the running TBF matches"
770
771 // Reset Control code.
772 l1pa_l1ps_com.transfer.ptcch.ta_update_cmd = FALSE;
773
774 } // End if(...ta_update_cmd == TRUE)
775
776 // LOOK FOR PSI PARAMETERS UPDATE
777 //===============================
778
779 if(l1pa_l1ps_com.transfer.psi_param.psi_param_update_cmd == TRUE)
780 {
781 // Update parameters
782 l1a_l1s_com.Scell_info.pb = l1pa_l1ps_com.transfer.psi_param.Scell_pb;
783 l1pa_l1ps_com.access_burst_type = l1pa_l1ps_com.transfer.psi_param.access_burst_type;
784
785 // Reset Control code.
786 l1pa_l1ps_com.transfer.psi_param.psi_param_update_cmd = FALSE;
787 }
788
789 /***********************************************************/
790 /* TBF release, PDCH release, Repeat allocation, Fixed */
791 /* allocation exhaustion */
792 /***********************************************************/
793
794 // These events are only taken into account on block boundaries
795 // in order to keep the "aset" structure unchanged for all the control phases
796 // of the last block before modification
797
798 if(block_boundary)
799 {
800 // LOOK FOR TBF TO BE RELEASED...
801 //===============================
802
803 if(l1pa_l1ps_com.transfer.tbf_release_param.tbf_release_cmd == TRUE)
804 {
805 xSignalHeaderRec *msg;
806
807 //TBF_changes
808 #if !FF_TBF
809 switch(l1pa_l1ps_com.transfer.tbf_release_param.released_tbf)
810 #else
811 UWORD8 released_tbf;
812
813 // Special case if we got a request to release a two phase access TBF:
814 // It is registered within ASET structure as an uplink TBF. If we are
815 // currently in pseudo TBF for two phase access, we process the request
816 // like an uplink release, otherwise we skip it and just send the
817 // L1P_TBF_RELEASED to L1A.
818
819 released_tbf = l1pa_l1ps_com.transfer.tbf_release_param.released_tbf;
820
821 if (released_tbf == TWO_PHASE_ACCESS)
822 {
823 if (l1pa_l1ps_com.transfer.aset->pseudo_tbf_two_phase_acc)
824 released_tbf = UL_TBF;
825 else
826 released_tbf = NO_TBF;
827 }
828
829 switch(released_tbf)
830 #endif
831 {
832 case UL_TBF:
833 {
834 if(l1pa_l1ps_com.transfer.aset->allocated_tbf == UL_TBF)
835 {
836 // Disable PDTCH task.
837 l1a_l1s_com.l1s_en_task[PDTCH] = TASK_DISABLED;
838 // Disable PTCCH task.
839 l1a_l1s_com.l1s_en_task[PTCCH] = TASK_DISABLED;
840
841 // Free the active set.
842 l1pa_l1ps_com.transfer.aset->allocated_tbf = NO_TBF;
843 }
844 else
845 if(l1pa_l1ps_com.transfer.aset->allocated_tbf == BOTH_TBF)
846 {
847 // Still DL_TBF running.
848 // We must synchro to the 1st timeslot of DL_TBF.
849
850 // REM: the new configuration is not flagged to MACS via "l1ps_macs_com.new_set"
851 // since MACS will detect the alloc change.
852
853 // Active set becomes DL TBF.
854 l1pa_l1ps_com.transfer.aset->allocated_tbf = DL_TBF;
855
856 // SYNCHRO task is not schedule if we are in the specific case:
857 // L1A is touching SYNCHRO parameters (tn_difference, dl_tn and dsp_scheduler_mode)
858 // and leave L1A to go in HISR (L1S) in middle of the update (cf. BUG1339)
859 // Note: tn_difference has to be accumulated in order to cope with the
860 // specific case: L1A has just updated tn_difference, dl_tn and dsp_scheduler_mode
861 // parameters and we enter in the HISR after the reset of the SYNCHRO Semaphore.
862 if(l1a_l1s_com.task_param[SYNCHRO] == SEMAPHORE_RESET)
863 {
864 l1a_l1s_com.tn_difference += l1pa_l1ps_com.transfer.aset->dl_tbf_synchro_timeslot - l1a_l1s_com.dl_tn;
865 l1a_l1s_com.dl_tn = l1pa_l1ps_com.transfer.aset->dl_tbf_synchro_timeslot;
866
867 // Enable SYNCHRO task only when camp timeslot is changed.
868 if(l1a_l1s_com.tn_difference != 0)
869 {
870 l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;
871 }
872 }
873
874 // Diable PTCCH if timeslot doesn't match with the remaining DL TBF allocation
875 if (!((0x80 >> l1pa_l1ps_com.transfer.aset->packet_ta.ta_tn) &
876 l1pa_l1ps_com.transfer.aset->dl_tbf_alloc.timeslot_alloc))
877 {
878 // Disable PTCCH task.
879 l1a_l1s_com.l1s_en_task[PTCCH] = TASK_DISABLED;
880
881 #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
882 l1_trace_ptcch_disable();
883 #endif
884 }
885
886 }
887
888 // Reset Repeat allocation starting time checking
889 l1pa_l1ps_com.transfer.repeat_alloc.repeat_allocation = FALSE;
890 // Reset Allocation Exhaustion detection flag
891 l1ps_macs_com.fix_alloc_exhaust_flag = FALSE;
892 #if L1_EDA
893 // Disable FB/SB task detection mechanism for MS class 12
894 l1ps_macs_com.fb_sb_task_detect = FALSE;
895 #endif
896 }
897 break;
898
899 case DL_TBF:
900 {
901 if(l1pa_l1ps_com.transfer.aset->allocated_tbf == DL_TBF)
902 {
903 // Disable PDTCH task.
904 l1a_l1s_com.l1s_en_task[PDTCH] = TASK_DISABLED;
905 // Disable PTCCH task.
906 l1a_l1s_com.l1s_en_task[PTCCH] = TASK_DISABLED;
907
908 // Free the active set.
909 l1pa_l1ps_com.transfer.aset->allocated_tbf = NO_TBF;
910 }
911 else
912 if(l1pa_l1ps_com.transfer.aset->allocated_tbf == BOTH_TBF)
913 {
914 // Still UL_TBF running.
915 // We must synchro to the 1st timeslot of UL_TBF.
916
917 // REM: the new configuration is not flagged to MACS via "l1ps_macs_com.new_set"
918 // since MACS will detect the alloc change.
919
920 // Active set becomes UL TBF.
921 l1pa_l1ps_com.transfer.aset->allocated_tbf = UL_TBF;
922
923 // SYNCHRO task is not schedule if we are in the specific case:
924 // L1A is touching SYNCHRO parameters (tn_difference, dl_tn and dsp_scheduler_mode)
925 // and leave L1A to go in HISR (L1S) in middle of the update (cf. BUG1339)
926 // Note: tn_difference has to be accumulated in order to cope with the
927 // specific case: L1A has just updated tn_difference, dl_tn and dsp_scheduler_mode
928 // parameters and we enter in the HISR after the reset of the SYNCHRO Semaphore.
929 if(l1a_l1s_com.task_param[SYNCHRO] == SEMAPHORE_RESET)
930 {
931 l1a_l1s_com.tn_difference += l1pa_l1ps_com.transfer.aset->ul_tbf_synchro_timeslot - l1a_l1s_com.dl_tn;
932 l1a_l1s_com.dl_tn = l1pa_l1ps_com.transfer.aset->ul_tbf_synchro_timeslot;
933
934 // Enable SYNCHRO task only when camp timeslot is changed.
935 if(l1a_l1s_com.tn_difference != 0)
936 {
937 l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;
938 }
939 }
940
941 // Diable PTCCH if timeslot doesn't match with the remaining UL TBF allocation
942 if (!((0x80 >> l1pa_l1ps_com.transfer.aset->packet_ta.ta_tn) &
943 l1pa_l1ps_com.transfer.aset->ul_tbf_alloc->timeslot_alloc))
944 {
945 // Disable PTCCH task.
946 l1a_l1s_com.l1s_en_task[PTCCH] = TASK_DISABLED;
947
948 #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
949 l1_trace_ptcch_disable();
950 #endif
951 }
952
953 }
954 }
955 break;
956
957 case BOTH_TBF:
958 {
959 // No more TBF...
960 // Disable PDTCH task.
961 l1a_l1s_com.l1s_en_task[PDTCH] = TASK_DISABLED;
962 // Disable PTCCH task.
963 l1a_l1s_com.l1s_en_task[PTCCH] = TASK_DISABLED;
964
965 // Free the active set.
966 l1pa_l1ps_com.transfer.aset->allocated_tbf = NO_TBF;
967
968 // Reset Repeat allocation starting time checking
969 l1pa_l1ps_com.transfer.repeat_alloc.repeat_allocation = FALSE;
970 // Reset Allocation Exhaustion detection flag
971 l1ps_macs_com.fix_alloc_exhaust_flag = FALSE;
972 #if L1_EDA
973 // Disable FB/SB task detection mechanism for MS class 12
974 l1ps_macs_com.fb_sb_task_detect = FALSE;
975 #endif
976 }
977 break;
978
979 }
980
981 // Send confirmation msg to L3/MACA.
982 msg = os_alloc_sig(sizeof(T_L1P_TBF_RELEASED));
983 DEBUGMSG(status,NU_ALLOC_ERR)
984
985 msg->SignalCode = L1P_TBF_RELEASED;
986
987 // initialize the TBF type for the confirmation msg
988 ((T_L1P_TBF_RELEASED *) msg->SigP)->tbf_type = l1pa_l1ps_com.transfer.tbf_release_param.released_tbf;
989
990 if (l1pa_l1ps_com.transfer.aset->allocated_tbf == NO_TBF)
991 {
992 /*
993 * FreeCalypso: removal of the following line is
994 * TCS211 reconstruction
995 */
996 //l1ps.read_param.assignment_id = 0x01; /* default non initialised value for next tbf */
997
998 ((T_L1P_TBF_RELEASED *) msg->SigP)->released_all = TRUE;
999
1000 #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37)
1001 // Correction of BUG1041: reset of multislot bit in d_bbctrl_gprs
1002 // when leaving patcket transfer.
1003 l1ps_dsp_com.pdsp_ndb_ptr->d_bbctrl_gprs = l1_config.params.bbctrl;
1004 #endif
1005 }
1006 else
1007 {
1008 ((T_L1P_TBF_RELEASED *) msg->SigP)->released_all = FALSE;
1009 }
1010
1011 // Insert "tn_difference" information in L1P_TBF_RELEASED msg
1012 // will be used in Ncell Dedic6 state machine to request a reset
1013 // or not of the state machine.
1014 ((T_L1P_TBF_RELEASED *) (msg->SigP))->tn_difference = l1a_l1s_com.tn_difference;
1015
1016 os_send_sig(msg, L1C1_QUEUE);
1017 DEBUGMSG(status,NU_SEND_QUEUE_ERR)
1018
1019 // Flag the new configuration in order to update the Read set parameters
1020 // with the "aset" structure modifications in the first PDTCH Read phase
1021 // after configuration change
1022 l1ps.read_param.new_set = TRUE;
1023
1024 // Reset Control code.
1025 l1pa_l1ps_com.transfer.tbf_release_param.tbf_release_cmd = FALSE;
1026 }
1027
1028 // LOOK FOR PDCH TO BE RELEASED...
1029 //================================
1030
1031 if(l1pa_l1ps_com.transfer.pdch_release_param.pdch_release_cmd == TRUE)
1032 {
1033 xSignalHeaderRec *msg;
1034 UWORD8 timeslot,timeslot_alloc;
1035
1036 // PDCH Release only apply if the assignement_id of the running TBF matches
1037 // with the assignment_id included in the MPHP_PDCH_RELEASE_REQ message
1038 if (l1pa_l1ps_com.transfer.pdch_release_param.assignment_id == l1pa_l1ps_com.transfer.aset->assignment_id)
1039 {
1040
1041 // Update timeslot allocation bitmaps
1042 l1pa_l1ps_com.transfer.aset->ul_tbf_alloc->timeslot_alloc &= l1pa_l1ps_com.transfer.pdch_release_param.timeslot_available;
1043 l1pa_l1ps_com.transfer.aset->dl_tbf_alloc.timeslot_alloc &= l1pa_l1ps_com.transfer.pdch_release_param.timeslot_available;
1044
1045 // Process the downlink TBF first allocated timeslot
1046 timeslot_alloc = l1pa_l1ps_com.transfer.aset->dl_tbf_alloc.timeslot_alloc;
1047 timeslot = 0;
1048
1049 while((timeslot<7) && !(timeslot_alloc & (0x80>>timeslot)))
1050 {
1051 timeslot++;
1052 }
1053
1054 l1pa_l1ps_com.transfer.aset->dl_tbf_synchro_timeslot = timeslot;
1055
1056 // Process the uplink TBF first allocated timeslot
1057 timeslot_alloc = l1pa_l1ps_com.transfer.aset->ul_tbf_alloc->timeslot_alloc;
1058 timeslot = 0;
1059 #if L1_EDA
1060 // Dynamic allocation mode or Extended Dynamic allocation mode
1061 if((l1pa_l1ps_com.transfer.aset->mac_mode == DYN_ALLOC) || (l1pa_l1ps_com.transfer.aset->mac_mode == EXT_DYN_ALLOC))
1062 #else
1063 // Dynamic allocation mode
1064 if(l1pa_l1ps_com.transfer.aset->mac_mode == DYN_ALLOC)
1065 #endif
1066 {
1067 while((timeslot<7) && !(timeslot_alloc & (0x80>>timeslot)))
1068 {
1069 timeslot++;
1070 }
1071 }
1072 else
1073 // Fixed allocation mode
1074 if(l1pa_l1ps_com.transfer.aset->mac_mode == FIX_ALLOC_NO_HALF)
1075 {
1076 // If the control timeslot hasn't been released
1077 if (l1pa_l1ps_com.transfer.aset->ul_tbf_alloc->timeslot_alloc &
1078 (0x80 >> l1pa_l1ps_com.transfer.aset->ul_tbf_alloc->fixed_alloc.ctrl_timeslot))
1079 {
1080 // The first allocated timeslot is the control timeslot
1081 timeslot = l1pa_l1ps_com.transfer.aset->ul_tbf_alloc->fixed_alloc.ctrl_timeslot;
1082 }
1083 else
1084 {
1085 // The first allocated timeslot is found in the allocation bitmap
1086 while((timeslot<7) && !(timeslot_alloc & (0x80>>timeslot)))
1087 {
1088 timeslot++;
1089 }
1090 }
1091 }
1092
1093 l1pa_l1ps_com.transfer.aset->ul_tbf_synchro_timeslot = timeslot;
1094
1095 // Fill "synchro_timeslot" which will be the frame synchro slot.
1096 switch(l1pa_l1ps_com.transfer.aset->allocated_tbf)
1097 {
1098 case(DL_TBF):
1099 {
1100 l1pa_l1ps_com.transfer.aset->transfer_synchro_timeslot = l1pa_l1ps_com.transfer.aset->dl_tbf_synchro_timeslot;
1101 }
1102 break;
1103
1104 case(UL_TBF):
1105 {
1106 l1pa_l1ps_com.transfer.aset->transfer_synchro_timeslot = l1pa_l1ps_com.transfer.aset->ul_tbf_synchro_timeslot;
1107 }
1108 break;
1109
1110 case(BOTH_TBF):
1111 {
1112 if (l1pa_l1ps_com.transfer.aset->dl_tbf_synchro_timeslot > l1pa_l1ps_com.transfer.aset->ul_tbf_synchro_timeslot)
1113 {
1114 l1pa_l1ps_com.transfer.aset->transfer_synchro_timeslot = l1pa_l1ps_com.transfer.aset->ul_tbf_synchro_timeslot;
1115 }
1116 else
1117 {
1118 l1pa_l1ps_com.transfer.aset->transfer_synchro_timeslot = l1pa_l1ps_com.transfer.aset->dl_tbf_synchro_timeslot;
1119 }
1120 }
1121 break;
1122 }
1123
1124 // SYNCHRO task is not schedule if we are in the specific case:
1125 // L1A is touching SYNCHRO parameters (tn_difference, dl_tn and dsp_scheduler_mode)
1126 // and leave L1A to go in HISR (L1S) in middle of the update (cf. BUG1339)
1127 // Note: tn_difference has to be accumulated in order to cope with the
1128 // specific case: L1A has just updated tn_difference, dl_tn and dsp_scheduler_mode
1129 // parameters and we enter in the HISR after the reset of the SYNCHRO Semaphore.
1130 if(l1a_l1s_com.task_param[SYNCHRO] == SEMAPHORE_RESET)
1131 {
1132 // New synchronization
1133 l1a_l1s_com.tn_difference += l1pa_l1ps_com.transfer.aset->transfer_synchro_timeslot - l1a_l1s_com.dl_tn;
1134 l1a_l1s_com.dl_tn = l1pa_l1ps_com.transfer.aset->transfer_synchro_timeslot;
1135
1136 // REM: the new configuration is not flagged to MACS via "l1ps_macs_com.new_set"
1137 // since MACS will detect the alloc change.
1138
1139 // Enable SYNCHRO task only when camp timeslot is changed.
1140 if(l1a_l1s_com.tn_difference != 0)
1141 {
1142 l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;
1143 }
1144 }
1145
1146 // Disable PTCCH if timeslot doesn't match with the remaining PDCH allocation
1147 if (!((0x80 >> l1pa_l1ps_com.transfer.aset->packet_ta.ta_tn) &
1148 l1pa_l1ps_com.transfer.pdch_release_param.timeslot_available))
1149 {
1150 // Disable PTCCH task.
1151 l1a_l1s_com.l1s_en_task[PTCCH] = TASK_DISABLED;
1152
1153 #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
1154 l1_trace_ptcch_disable();
1155 #endif
1156 }
1157
1158 // Send confirmation msg to L3/MACA.
1159 msg = os_alloc_sig(sizeof(T_L1P_PDCH_RELEASE_CON));
1160 DEBUGMSG(status,NU_ALLOC_ERR)
1161
1162 msg->SignalCode = L1P_PDCH_RELEASED;
1163
1164 ((T_L1P_PDCH_RELEASE_CON *) msg->SigP)->assignment_id = l1pa_l1ps_com.transfer.pdch_release_param.assignment_id;
1165
1166 // Insert "tn_difference" information in T_L1P_PDCH_RELEASE_CON msg
1167 // will be used in Ncell Dedic6 state machine to request a reset
1168 // or not of the state machine
1169 ((T_L1P_PDCH_RELEASE_CON *) (msg->SigP))->tn_difference = l1a_l1s_com.tn_difference;
1170
1171 os_send_sig(msg, L1C1_QUEUE);
1172 DEBUGMSG(status,NU_SEND_QUEUE_ERR)
1173
1174 // Flag the new configuration in order to update the Read set parameters
1175 // with the "aset" structure modifications in the first PDTCH Read phase
1176 // after configuration change
1177 l1ps.read_param.new_set = TRUE;
1178
1179 } // End if "assignment_id matches with the running TBF"
1180
1181 // Reset Control code.
1182 l1pa_l1ps_com.transfer.pdch_release_param.pdch_release_cmd = FALSE;
1183 }
1184
1185 // LOOK FOR REPEAT ALLOCATION ...
1186 //================================
1187
1188 if(l1pa_l1ps_com.transfer.repeat_alloc.repeat_allocation)
1189 {
1190 UWORD8 timeslot,timeslot_alloc;
1191
1192 // Starting time checking...
1193 //--------------------------
1194
1195 if(l1pa_l1ps_com.transfer.repeat_alloc.tbf_sti.present)
1196 // Starting time present.
1197 // Rem: starting time detected 1 frame in advance, this frame is used by
1198 // SYNCHRO task.
1199 {
1200 WORD32 time_diff;
1201
1202 // If synchro change occurs, it's always from a timeslot N to N + 1
1203 time_diff = ( (l1pa_l1ps_com.transfer.repeat_alloc.tbf_sti.absolute_fn - 1)
1204 - (l1s.next_time.fn % 42432) + 2*42432) % 42432;
1205
1206 // Starting time has been passed...
1207 if(((time_diff >= (32024)) && (time_diff <= (42431))) || (time_diff == 0))
1208 {
1209 l1pa_l1ps_com.transfer.repeat_alloc.tbf_sti.present = FALSE;
1210 }
1211 } // End if "starting time present"
1212
1213 // Starting time passed...
1214 //------------------------
1215
1216 // If the repeat allocation starts on this frame...
1217 if (!l1pa_l1ps_com.transfer.repeat_alloc.tbf_sti.present)
1218 {
1219 #if (TRACE_TYPE!=0)
1220 // Trace "starting time" on log file and screen.
1221 trace_fct(CST_STI_PASSED, l1a_l1s_com.Scell_info.radio_freq);
1222 #endif
1223
1224 // Update ts_override and starting time
1225 l1pa_l1ps_com.transfer.aset->ts_override = l1pa_l1ps_com.transfer.repeat_alloc.ts_override;
1226 l1pa_l1ps_com.transfer.aset->tbf_sti.absolute_fn = l1pa_l1ps_com.transfer.repeat_alloc.tbf_sti.absolute_fn;
1227
1228 // Lowest allocated timeslot for the UL TBF
1229
1230 // If the downlink control timeslot hasn't been released: it's the downlink control timeslot
1231 // Else no change
1232 if ( l1pa_l1ps_com.transfer.aset->ul_tbf_alloc->timeslot_alloc
1233 & (0x80 >> l1pa_l1ps_com.transfer.aset->ul_tbf_alloc->fixed_alloc.ctrl_timeslot))
1234 {
1235 // Synchronization on the downlink control timeslot
1236 l1pa_l1ps_com.transfer.aset->ul_tbf_synchro_timeslot = l1pa_l1ps_com.transfer.aset->ul_tbf_alloc->fixed_alloc.ctrl_timeslot;
1237 }
1238
1239 // Synchronization
1240
1241 // If a downlink TBF is enabled
1242 if ( l1pa_l1ps_com.transfer.aset->allocated_tbf == BOTH_TBF)
1243 {
1244 // Synchronization on the downlink TBF lowest allocated timeslot ?
1245 if (l1pa_l1ps_com.transfer.aset->ul_tbf_synchro_timeslot > l1pa_l1ps_com.transfer.aset->dl_tbf_synchro_timeslot)
1246 l1pa_l1ps_com.transfer.aset->transfer_synchro_timeslot = l1pa_l1ps_com.transfer.aset->dl_tbf_synchro_timeslot;
1247 else
1248 l1pa_l1ps_com.transfer.aset->transfer_synchro_timeslot = l1pa_l1ps_com.transfer.aset->ul_tbf_synchro_timeslot;
1249 }
1250 // Else: synchronization on the uplink TBF lowest allocated timeslot
1251 else
1252 l1pa_l1ps_com.transfer.aset->transfer_synchro_timeslot = l1pa_l1ps_com.transfer.aset->ul_tbf_synchro_timeslot;
1253
1254 // SYNCHRO task is not schedule if we are in the specific case:
1255 // L1A is touching SYNCHRO parameters (tn_difference, dl_tn and dsp_scheduler_mode)
1256 // and leave L1A to go in HISR (L1S) in middle of the update (cf. BUG1339)
1257 // Note: tn_difference has to be accumulated in order to cope with the
1258 // specific case: L1A has just updated tn_difference, dl_tn and dsp_scheduler_mode
1259 // parameters and we enter in the HISR after the reset of the SYNCHRO Semaphore.
1260 if(l1a_l1s_com.task_param[SYNCHRO] == SEMAPHORE_RESET)
1261 {
1262 l1a_l1s_com.tn_difference += l1pa_l1ps_com.transfer.aset->transfer_synchro_timeslot - l1a_l1s_com.dl_tn;
1263 l1a_l1s_com.dl_tn = l1pa_l1ps_com.transfer.aset->transfer_synchro_timeslot;
1264
1265 // Enable SYNCHRO task only when camp timeslot is changed.
1266 if(l1a_l1s_com.tn_difference != 0)
1267 {
1268 l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;
1269 }
1270 }
1271
1272 // Set assignment_command to the last enabled TBF type.
1273 // This permits MAC-S to correctly manage TBF boundary conditions.
1274 if ((current_assignment_command == NO_TBF) || (current_assignment_command == UL_TBF))
1275 l1pa_l1ps_com.transfer.aset->assignment_command = UL_TBF;
1276 else
1277 l1pa_l1ps_com.transfer.aset->assignment_command = BOTH_TBF;
1278
1279 // Flag the new configuration to MACS.
1280 l1ps_macs_com.new_set = TRUE;
1281
1282 // Flag the new configuration in order to update the Read set parameters
1283 // with the "aset" structure modifications in the first PDTCH Read phase
1284 // after configuration change
1285 l1ps.read_param.new_set = TRUE;
1286
1287 // Reset Repeat allocation starting time checking
1288 l1pa_l1ps_com.transfer.repeat_alloc.repeat_allocation = FALSE;
1289 // Reset Allocation Exhaustion detection flag
1290 l1ps_macs_com.fix_alloc_exhaust_flag = FALSE;
1291
1292 // Send confirmation
1293 {
1294 xSignalHeaderRec *msg;
1295
1296 // Send confirmation msg to L3/MACA.
1297 msg = os_alloc_sig(sizeof(T_L1P_REPEAT_ALLOC_DONE));
1298 DEBUGMSG(status,NU_ALLOC_ERR)
1299
1300 msg->SignalCode = L1P_REPEAT_ALLOC_DONE;
1301
1302 // Insert "tn_difference" information in T_L1P_REPEAT_ALLOC_DONE msg
1303 // will be used in Ncell Dedic6 state machine to request a reset
1304 // or not of the state machine
1305 ((T_L1P_REPEAT_ALLOC_DONE *) (msg->SigP))->tn_difference = l1a_l1s_com.tn_difference;
1306
1307 os_send_sig(msg, L1C1_QUEUE);
1308 DEBUGMSG(status,NU_SEND_QUEUE_ERR)
1309 }
1310
1311 } // End if "Repeat allocation starts this frame..."
1312 } // End of "Repeat allocation starting time checking"
1313
1314 // LOOK FOR FIXED MODE ALLOCATION BITMAP EXHAUSTION ...
1315 //==================================================
1316
1317 if(l1ps_macs_com.fix_alloc_exhaust_flag)
1318 {
1319 #if (TRACE_TYPE!=0)
1320 // Trace "starting time" on log file and screen.
1321 trace_fct(CST_ALLOC_EXHAUSTION, l1a_l1s_com.Scell_info.radio_freq);
1322 #endif
1323
1324 // Update uplink TBF synchronization timeslot
1325 {
1326 UWORD8 timeslot = 0;
1327 UWORD8 bitmap = 0x80;
1328
1329 while (!(l1pa_l1ps_com.transfer.aset->ul_tbf_alloc->timeslot_alloc & bitmap))
1330 {
1331 timeslot ++;
1332 bitmap >>= 1;
1333 }
1334
1335 // Synchronization on the lowest allocated timeslot for uplink tranfer
1336 l1pa_l1ps_com.transfer.aset->ul_tbf_synchro_timeslot = timeslot;
1337 }
1338
1339 // New synchronization only done on a timeslot inferior to current synchronization
1340 // - if a DL TBF is present: the DL TBF synchronization is taken into account
1341 // - an UL TBF is present: synchronization can only be done on a timeslot number inferior or
1342 // equal to the current synchronization
1343 if (l1pa_l1ps_com.transfer.aset->ul_tbf_synchro_timeslot <
1344 l1pa_l1ps_com.transfer.aset->transfer_synchro_timeslot)
1345 {
1346 l1pa_l1ps_com.transfer.aset->transfer_synchro_timeslot = l1pa_l1ps_com.transfer.aset->ul_tbf_synchro_timeslot;
1347 }
1348
1349 // SYNCHRO task is not schedule if we are in the specific case:
1350 // L1A is touching SYNCHRO parameters (tn_difference, dl_tn and dsp_scheduler_mode)
1351 // and leave L1A to go in HISR (L1S) in middle of the update (cf. BUG1339)
1352 // Note: tn_difference has to be accumulated in order to cope with the
1353 // specific case: L1A has just updated tn_difference, dl_tn and dsp_scheduler_mode
1354 // parameters and we enter in the HISR after the reset of the SYNCHRO Semaphore.
1355 if(l1a_l1s_com.task_param[SYNCHRO] == SEMAPHORE_RESET)
1356 {
1357 l1a_l1s_com.tn_difference += l1pa_l1ps_com.transfer.aset->transfer_synchro_timeslot - l1a_l1s_com.dl_tn;
1358 l1a_l1s_com.dl_tn = l1pa_l1ps_com.transfer.aset->transfer_synchro_timeslot;
1359
1360 // Enable SYNCHRO task only when camp timeslot is changed.
1361 if(l1a_l1s_com.tn_difference != 0)
1362 {
1363 l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;
1364 }
1365 }
1366
1367 // Send signal to L1A
1368 {
1369 xSignalHeaderRec *msg;
1370
1371 // Send confirmation msg to L3/MACA.
1372 msg = os_alloc_sig(sizeof(T_L1P_ALLOC_EXHAUST_DONE));
1373 DEBUGMSG(status,NU_ALLOC_ERR)
1374
1375 msg->SignalCode = L1P_ALLOC_EXHAUST_DONE;
1376
1377 // Insert "tn_difference" information in T_L1P_ALLOC_EXHAUST_DONE msg
1378 // will be used in Ncell Dedic6 state machine to request a reset
1379 // or not of the state machine
1380 ((T_L1P_ALLOC_EXHAUST_DONE *) (msg->SigP))->tn_difference = l1a_l1s_com.tn_difference;
1381
1382 os_send_sig(msg, L1C1_QUEUE);
1383 DEBUGMSG(status,NU_SEND_QUEUE_ERR)
1384 }
1385
1386 // Flag the new configuration in order to update the Read set parameters
1387 // with the "aset" structure modifications in the first PDTCH Read phase
1388 // after configuration change
1389 l1ps.read_param.new_set = TRUE;
1390
1391 // Reset flag
1392 l1ps_macs_com.fix_alloc_exhaust_flag = FALSE;
1393
1394 } // End if "fixed mode allocation bitmap has exhausted"
1395 } // End of "block_boundary"
1396 } // end of if(!l1pa_l1ps_com.transfer.semaphore)
1397 }
1398 //#pragma DUPLICATE_FOR_INTERNAL_RAM_END
1399 #endif // MOVE_IN_INTERNAL_RAM
1400
1401 #if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM !=0)) // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM enabled
1402 //#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_START // KEEP IN EXTERNAL MEM otherwise
1403
1404 /*-------------------------------------------------------*/
1405 /* l1ps_meas_manager() */
1406 /*-------------------------------------------------------*/
1407 /* */
1408 /* Description: */
1409 /* ------------ */
1410 /* This function is the tasks manager for Packet Cell */
1411 /* Reselection. */
1412 /* The followings tasks are handled: */
1413 /* */
1414 /* FSMS_MEAS: */
1415 /* */
1416 /* P_CRMS_MEAS: Packet Cell Reselection measurement */
1417 /* in Idle mode. The task includes: */
1418 /* o BA(GPRS) measurement */
1419 /* o Network controlled meas. */
1420 /* o Extended measurement */
1421 /* Occurrences are performed in order to satisfy the */
1422 /* following ETSI constraints: */
1423 /* 1. At least one measure of each BA BCCH carrier shall */
1424 /* be taken for each paging block, */
1425 /* 2. A minimum of one measure for each BA BCCH carrier */
1426 /* for every 4 second must be performed, */
1427 /* 3. MS is not required to take more than one sample */
1428 /* per second for each BCCH carrier, */
1429 /* 4. At least 5 measures per BA BCCH carrier are */
1430 /* required for a valid received level average value */
1431 /* (RLA_P), */
1432 /* 5. RLA_P shall be based on samples collected over a */
1433 /* period of 5s to Max{5s, five consecutive PPCH */
1434 /* blocks dedicated to the MS}, */
1435 /* 6. Samples allocated to each carrier shall as far */
1436 /* as possible be uniformly distributed over the */
1437 /* evaluation period. */
1438 /* */
1439 /* A TI condition is include: */
1440 /* 7. In order to save power consumption, it will be */
1441 /* necessary to use as far as possible the PPCH */
1442 /* blocks to perform a maximum of measurements during */
1443 /* these frames. */
1444 /* */
1445 /* From the previous constraints, it appears that */
1446 /* Paging block period needs to be considered to fit */
1447 /* ETSI consideration. */
1448 /* Tow case are considered: */
1449 /* o PPCH period >= 1s */
1450 /* o PPCH period < 1s */
1451 /* */
1452 /* Once all carriers of the frequency list have been */
1453 /* measured, a reporting message L1P_CR_MEAS_DONE is */
1454 /* built and sent to L1A. */
1455 /*-------------------------------------------------------*/
1456 void l1ps_meas_manager()
1457 {
1458 enum states
1459 {
1460 NULL_MEAS = 0,
1461 PCHTOTAL = 1,
1462 TOTAL = 2,
1463 MEAS = 3,
1464 MEASTOTAL = 4
1465 };
1466
1467 UWORD8 IL_for_rxlev;
1468 BOOL init_meas = FALSE;
1469 #if (RF_FAM == 61)
1470 UWORD16 dco_algo_ctl_pw = 0;
1471 UWORD16 dco_algo_ctl_pw_temp = 0;
1472 UWORD8 if_ctl = 0;
1473 UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
1474 #endif
1475 #define cr_list_size l1pa_l1ps_com.cres_freq_list.alist->nb_carrier
1476
1477 static WORD8 remain_carrier;
1478 static UWORD8 nbr_meas;
1479 static BOOL schedule_trigger;
1480 static xSignalHeaderRec *cr_msg = NULL;
1481 static WORD16 time_to_wake_up;
1482 static WORD16 time_to_4s;
1483 static WORD16 time_to_1s;
1484 static UWORD32 fn_update;
1485 static UWORD16 session_done; // Did a session of measures performed in the 4s period
1486 static UWORD16 session_done_1s; // Did a session of measures performed in the 1s period
1487 static UWORD8 state;
1488 static UWORD32 reporting_period; // Parameter used in "reporting_period" computation
1489
1490 #if (FF_L1_FAST_DECODING == 1)
1491 if (l1a_apihisr_com.fast_decoding.deferred_control_req == TRUE)
1492 {
1493 /* Do not execute l1s_meas_manager if a fast decoding IT is scheduled */
1494 return;
1495 }
1496 #endif /*#if (FF_L1_FAST_DECODING == 1)*/
1497
1498 #if FF_L1_IT_DSP_USF
1499 if (l1ps_macs_com.usf_status != USF_IT_DSP)
1500 {
1501 #endif
1502
1503
1504 //====================================================
1505 // RESET MEASUREMENT MACHINES WHEN ABORT EXECUTED.
1506 //====================================================
1507 if(l1s.dsp_ctrl_reg & CTRL_ABORT)
1508 // ABORT task has been controlled, which reset the MCU/DSP communication.
1509 // We must rewind any measurement activity.
1510 {
1511 // Aborted measurements have to be rescheduled
1512 nbr_meas += l1pa_l1ps_com.cr_freq_list.ms_ctrl_d + l1pa_l1ps_com.cr_freq_list.ms_ctrl_dd;
1513
1514 // Rewind "next_to_ctrl" counter to come back to the next carrier to
1515 // measure.
1516 l1pa_l1ps_com.cr_freq_list.next_to_ctrl = l1pa_l1ps_com.cr_freq_list.next_to_read;
1517
1518 // Reset flags.
1519 l1pa_l1ps_com.cr_freq_list.ms_ctrl = 0;
1520 l1pa_l1ps_com.cr_freq_list.ms_ctrl_d = 0;
1521 l1pa_l1ps_com.cr_freq_list.ms_ctrl_dd = 0;
1522 }
1523
1524 #if (GSM_IDLE_RAM != 1)
1525 // Test if task is disabled and cr_msg != NULL, then de-allocate memory
1526 if (!(l1pa_l1ps_com.l1ps_en_meas & P_CRMS_MEAS) && !(l1pa_l1ps_com.meas_param & P_CRMS_MEAS))
1527 {
1528 if(cr_msg != NULL)
1529 {
1530 // Cell reselection measurement process has been stopped by L3
1531 // Deallocate memory for the received message if msg not forwarded to L3.
1532 // ----------------------------------------------------------------------
1533 os_free_sig(cr_msg);
1534 DEBUGMSG(status,NU_DEALLOC_ERR)
1535
1536 cr_msg = NULL;
1537 }
1538 }
1539 #endif
1540
1541 if((l1pa_l1ps_com.l1ps_en_meas & P_CRMS_MEAS) && (l1pa_l1ps_com.meas_param & P_CRMS_MEAS))
1542 // Some changes occured on the Frequency list or the PAGING PARAMETERS have
1543 // changed.
1544 {
1545 // Reset Packet Cell Reselection semaphore.
1546 l1pa_l1ps_com.meas_param &= P_CRMS_MEAS_MASK;
1547
1548 // Paging process has been interrupted by a L3 message
1549 // Deallocate memory for the received message if msg not forwarded to L3.
1550 // ----------------------------------------------------------------------
1551
1552 //Update Frequency list pointer
1553 l1pa_l1ps_com.cres_freq_list.alist = l1pa_l1ps_com.cres_freq_list.flist;
1554
1555 // Rewind frequency list counters to come back to the first carrier of this
1556 // aborted session.
1557 l1pa_l1ps_com.cr_freq_list.next_to_read = 0;
1558 l1pa_l1ps_com.cr_freq_list.next_to_ctrl = 0;
1559
1560 // Reset flags.
1561 l1pa_l1ps_com.cr_freq_list.ms_ctrl = 0;
1562 l1pa_l1ps_com.cr_freq_list.ms_ctrl_d = 0;
1563 l1pa_l1ps_com.cr_freq_list.ms_ctrl_dd = 0;
1564
1565 // Initialize timer
1566 time_to_wake_up = 0;
1567 time_to_4s = 866;
1568 time_to_1s = 216;
1569 fn_update = l1s.actual_time.fn;
1570
1571 // Initialize Reporting Period
1572 reporting_period = l1s.actual_time.fn;
1573
1574 // Initialize Cell reselection state machine and parameters
1575 state = NULL_MEAS;
1576 session_done = 0;
1577 session_done_1s = 0;
1578 schedule_trigger = TRUE;
1579 nbr_meas = 0;
1580 init_meas = TRUE;
1581 }
1582 #if FF_L1_IT_DSP_USF
1583 } // if (l1ps_macs_com.usf_status != USF_IT_DSP)
1584 #endif
1585
1586 // Packet Idle Cell Relselection Power Measurements fonction if P_CRMS_MEAS task still enabled.
1587 // In case L1S has switched in GPRS packet transfer mode and L1S_TRANSFER_DONE message hasn't been processed yet
1588 // by L1A, no control or read task shall be done.
1589
1590 if ((l1pa_l1ps_com.l1ps_en_meas & P_CRMS_MEAS) && !(l1pa_l1ps_com.meas_param & P_CRMS_MEAS)
1591 && (l1a_l1s_com.l1s_en_task[PDTCH] != TASK_ENABLED))
1592 {
1593 #if FF_L1_IT_DSP_USF
1594 if (l1ps_macs_com.usf_status != USF_IT_DSP)
1595 {
1596 #endif
1597 // Update P_CRMS_MEAS timers
1598 {
1599 UWORD16 fn_diff;
1600 #define current_fn l1s.actual_time.fn
1601
1602 // Compute Frame Number increment since last L1S activity
1603 if(current_fn >= fn_update)
1604 fn_diff = current_fn - fn_update;
1605 else
1606 fn_diff = (current_fn + MAX_FN) - fn_update;
1607
1608 // Update timer
1609 time_to_4s -= fn_diff;
1610
1611 if(time_to_4s <= 0)
1612 {
1613 time_to_4s += 866;
1614 session_done = 0;
1615 }
1616
1617 time_to_1s -= fn_diff;
1618
1619 if(time_to_1s <= 0)
1620 {
1621 time_to_1s += 216;
1622 session_done_1s = 0;
1623 }
1624
1625 // Note: time to next meas position is negative during the meas.
1626 // session period
1627 time_to_wake_up -= fn_diff;
1628
1629 fn_update = current_fn;
1630 }
1631
1632 if(time_to_wake_up == 0)
1633 {
1634 // Schedule CR meas position for "PNP period >= 1s" case
1635 if(l1pa_l1ps_com.pccch.pnp_period >= 216)
1636 {
1637 switch (state)
1638 {
1639 case PCHTOTAL:
1640 case TOTAL:
1641 {
1642 nbr_meas = cr_list_size;
1643
1644 // Measures is going to start, set "session_done" flag.
1645 // "session_done" flag must be set at the begining of a meas. session
1646 // in order to be able to detect crossing of the 4s boundary
1647 session_done = 1;
1648 }
1649 break;
1650
1651 case NULL_MEAS:
1652 {
1653 nbr_meas = 0;
1654 }
1655 break;
1656 }
1657 }
1658 // Schedule CR meas position for "PNP period < 1s" case
1659 else
1660 {
1661 switch (state)
1662 {
1663 case NULL_MEAS:
1664 {
1665 nbr_meas = 0;
1666 }
1667 break;
1668
1669 case MEAS:
1670 {
1671 UWORD8 max_nbmeas;
1672 WORD16 tpu_win_rest;
1673 UWORD16 power_meas_split;
1674
1675 // Compute how many BP_SPLIT remains for cr list meas
1676 // Rem: we take into account the SYNTH load for 1st RX in next frame.
1677 // WARNING: only one RX activity is considered in next paging block !!!
1678 tpu_win_rest = FRAME_SPLIT - (RX_LOAD + l1_config.params.rx_synth_load_split);
1679
1680 power_meas_split = (l1_config.params.rx_synth_load_split + PWR_LOAD);
1681 max_nbmeas = 0;
1682
1683 while(tpu_win_rest >= power_meas_split)
1684 {
1685 max_nbmeas ++;
1686 tpu_win_rest -= power_meas_split;
1687 }
1688
1689 if (max_nbmeas > NB_MEAS_MAX_GPRS) max_nbmeas = NB_MEAS_MAX_GPRS;
1690
1691 // There is no more PPCH block before end of 1s period.
1692 // End remaining carriers.
1693 nbr_meas = Min(remain_carrier, 4*max_nbmeas);
1694
1695 // Measures is going to start, set "session_done" flag.
1696 // "session_done_1s" flag must be set at the begining of a meas. session
1697 // in order to be able to detect crossing of the 1s boundary
1698 session_done_1s = 1;
1699
1700 }
1701 break;
1702
1703 case MEASTOTAL:
1704 {
1705 nbr_meas = remain_carrier;
1706
1707 // Measures is going to start, set "session_done" flag.
1708 // "session_done_1s" flag must be set at the begining of a meas. session
1709 // in order to be able to detect crossing of the 1s boundary
1710 session_done_1s = 1;
1711
1712 }
1713 break;
1714 }
1715 } // End of else ("PNP period < 1s" case)
1716 }
1717
1718 /* --------------------------------------------------------------------*/
1719 /* CTRL and READ phase carrying out. "nbr_meas" measures are performed */
1720 /* --------------------------------------------------------------------*/
1721
1722 // ********************
1723 // READ task if needed
1724 // ********************
1725 if(l1pa_l1ps_com.cr_freq_list.ms_ctrl_dd)
1726 // Background measurements....
1727 // A measure CTRL was performed 2 tdma earlier, read result now.
1728 {
1729 UWORD16 radio_freq_read;
1730 UWORD8 pm_read[NB_MEAS_MAX_GPRS];
1731 UWORD8 i;
1732
1733 #define next_to_read l1pa_l1ps_com.cr_freq_list.next_to_read
1734
1735 // When a READ is performed we set dsp_r_page_used flag to
1736 // switch the read page.
1737 l1s_dsp_com.dsp_r_page_used = TRUE;
1738
1739 l1_check_com_mismatch(CR_MEAS_ID);
1740
1741 // Read power measurement result from DSP/MCU GPRS interface
1742 l1pddsp_meas_read(l1pa_l1ps_com.cr_freq_list.ms_ctrl_dd, pm_read);
1743
1744 for(i=0; i<l1pa_l1ps_com.cr_freq_list.ms_ctrl_dd; i++)
1745 {
1746 radio_freq_read = l1pa_l1ps_com.cres_freq_list.alist->freq_list[next_to_read];
1747
1748 // Traces and debug.
1749 // ******************
1750
1751 #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
1752 trace_fct(CST_READ_CR_MEAS, radio_freq_read);
1753 #endif
1754
1755 l1_check_pm_error(pm_read[i], CR_MEAS_ID);
1756
1757 // Get Input level corresponding to the used IL and pm result.
1758 IL_for_rxlev = l1pctl_pgc(((UWORD8)(pm_read[i])),
1759 l1pa_l1ps_com.cr_freq_list.used_il_lna_dd[i].il,
1760 l1pa_l1ps_com.cr_freq_list.used_il_lna_dd[i].lna,
1761 radio_freq_read);
1762
1763 #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
1764 RTTL1_FILL_MON_MEAS(pm_read[i], IL_for_rxlev, CR_MEAS_ID, radio_freq_read)
1765 #endif
1766
1767 // Check that cr_msg hasn't been erased.
1768 if (cr_msg == NULL)
1769 {
1770 cr_msg = os_alloc_sig(sizeof(T_L1P_CR_MEAS_DONE));
1771 DEBUGMSG(status,NU_ALLOC_ERR)
1772 cr_msg->SignalCode = L1P_CR_MEAS_DONE;
1773 }
1774
1775 #if (GSM_IDLE_RAM != 1)
1776 // Fill reporting message.
1777 ((T_L1P_CR_MEAS_DONE*)(cr_msg->SigP))->
1778 ncell_meas[next_to_read].rxlev = l1s_encode_rxlev(IL_for_rxlev);
1779 #else
1780 // Fill reporting message.
1781 l1ps.ncell_meas_rxlev[next_to_read] = (WORD8) l1s_encode_rxlev(IL_for_rxlev);
1782 #endif
1783 // Increment "next_to_read" field for next measurement...
1784 if(++next_to_read >= cr_list_size)
1785 next_to_read = 0;
1786 }//end for
1787
1788 // **********
1789 // Reporting
1790 // **********
1791 if(next_to_read == 0)
1792 {
1793 #if (GSM_IDLE_RAM == 1)
1794 // Check if memory for L1P_CR_MEAS_DONE msg is allocated
1795 if (cr_msg == NULL)
1796 {
1797 if (!READ_TRAFFIC_CONT_STATE)
1798 CSMI_TrafficControllerOn();
1799 cr_msg = os_alloc_sig(sizeof(T_L1P_CR_MEAS_DONE));
1800 DEBUGMSG(status,NU_ALLOC_ERR)
1801 cr_msg->SignalCode = L1P_CR_MEAS_DONE;
1802 }
1803
1804 for(i=0; i<cr_list_size; i++)
1805 {
1806 ((T_L1P_CR_MEAS_DONE*)(cr_msg->SigP))->ncell_meas[i].rxlev = l1ps.ncell_meas_rxlev[i];
1807 // Fill reporting message.
1808 }
1809 #endif
1810
1811 // Fill BA identifier field.
1812 ((T_L1P_CR_MEAS_DONE*)(cr_msg->SigP))->list_id = l1pa_l1ps_com.cres_freq_list.alist->list_id;
1813
1814 ((T_L1P_CR_MEAS_DONE*)(cr_msg->SigP))->nmeas = cr_list_size;
1815
1816 // Compute and Fill reporting period value
1817 if(l1s.actual_time.fn > reporting_period)
1818 reporting_period = l1s.actual_time.fn - reporting_period;
1819 else
1820 reporting_period = l1s.actual_time.fn - reporting_period + MAX_FN;
1821
1822 ((T_L1P_CR_MEAS_DONE*)(cr_msg->SigP))->reporting_period = (UWORD16)reporting_period;
1823
1824 reporting_period = l1s.actual_time.fn;
1825
1826 // send L1P_CR_MEAS_DONE message...
1827 os_send_sig(cr_msg, L1C1_QUEUE);
1828 DEBUGMSG(status,NU_SEND_QUEUE_ERR)
1829
1830 // Reset pointer for debugg.
1831 cr_msg = NULL;
1832 }
1833
1834 // Trigger measurement scheduler when meas. session is completed.
1835 // Note: A meas. session includes all carriers of the list "PNP period >= 1s case"
1836 // or only a sub-set of the CR freq list "PNP period < 1s case"
1837 if(!(l1pa_l1ps_com.cr_freq_list.ms_ctrl) && !(l1pa_l1ps_com.cr_freq_list.ms_ctrl_d))
1838 schedule_trigger = TRUE;
1839 }// end of READ
1840
1841 #if FF_L1_IT_DSP_USF
1842 } // if (l1ps_macs_com.usf_status != USF_IT_DSP)
1843 #endif
1844
1845 // **********
1846 // CTRL task
1847 // **********
1848
1849 #if FF_L1_IT_DSP_USF
1850 if (l1ps_macs_com.usf_status != USF_AWAITED)
1851 {
1852 #endif
1853
1854 if (nbr_meas > 0)
1855 {
1856 if(l1s.forbid_meas < 2)
1857 {
1858 UWORD8 max_nbmeas;
1859 UWORD8 nb_meas_to_perform;
1860 UWORD16 radio_freq_ctrl;
1861 UWORD8 i;
1862 UWORD8 pw_position = 0; // indicates first time slot in frame available for PM
1863 WORD16 tpu_win_rest;
1864 UWORD16 power_meas_split;
1865
1866 #define next_to_ctrl l1pa_l1ps_com.cr_freq_list.next_to_ctrl
1867
1868 // Compute how many BP_SPLIT remains for cr list meas
1869 // Rem: we take into account the SYNTH load for 1st RX in next frame.
1870 tpu_win_rest = FRAME_SPLIT - l1s.tpu_win;
1871 power_meas_split = (l1_config.params.rx_synth_load_split + PWR_LOAD);
1872 max_nbmeas = 0;
1873
1874 while(tpu_win_rest >= power_meas_split)
1875 {
1876 max_nbmeas ++;
1877 tpu_win_rest -= power_meas_split;
1878 }
1879
1880 // Compute number of PM allowed in the Frame
1881 // Test if we are on a Paging frame
1882 if(l1pa_l1ps_com.cr_freq_list.pnp_ctrl > 0) pw_position = 1;
1883
1884 // Test if PRACH controlled in the same frame
1885 if(l1s.tpu_win >= ((3 * BP_SPLIT) + l1_config.params.tx_ra_load_split
1886 + l1_config.params.rx_synth_load_split))
1887 {
1888 pw_position = 4;
1889 }
1890
1891 // Compute Number of measures to perform
1892 nb_meas_to_perform = cr_list_size - next_to_ctrl;
1893
1894 if(nb_meas_to_perform > max_nbmeas)
1895 nb_meas_to_perform = max_nbmeas;
1896
1897 if(nb_meas_to_perform > NB_MEAS_MAX_GPRS)
1898 nb_meas_to_perform = NB_MEAS_MAX_GPRS;
1899
1900 if (nb_meas_to_perform > nbr_meas)
1901 nb_meas_to_perform = nbr_meas;
1902
1903 for(i=0; i<nb_meas_to_perform; i++)
1904 {
1905 UWORD8 lna_off;
1906 WORD8 agc;
1907 UWORD8 input_level;
1908 #if (L1_FF_MULTIBAND == 1)
1909 UWORD16 operative_radio_freq;
1910 #endif
1911
1912 radio_freq_ctrl = l1pa_l1ps_com.cres_freq_list.alist->freq_list[next_to_ctrl];
1913
1914 #if (L1_FF_MULTIBAND == 0)
1915
1916 // Get AGC according to the last known IL.
1917 input_level = l1a_l1s_com.last_input_level[radio_freq_ctrl - l1_config.std.radio_freq_index_offset].input_level;
1918 agc = Cust_get_agc_from_IL(radio_freq_ctrl,input_level >> 1, PWR_ID);
1919 lna_off = l1a_l1s_com.last_input_level[radio_freq_ctrl - l1_config.std.radio_freq_index_offset].lna_off;
1920
1921
1922 // Memorize the IL and LNA used for AGC setting.
1923 //l1pa_l1ps_com.cr_freq_list.used_il_lna[i] = l1a_l1s_com.last_input_level[radio_freq_ctrl - l1_config.std.radio_freq_index_offset];
1924 l1pa_l1ps_com.cr_freq_list.used_il_lna[i].il = l1a_l1s_com.last_input_level[radio_freq_ctrl - l1_config.std.radio_freq_index_offset].input_level;
1925 l1pa_l1ps_com.cr_freq_list.used_il_lna[i].lna = l1a_l1s_com.last_input_level[radio_freq_ctrl - l1_config.std.radio_freq_index_offset].lna_off;
1926
1927 #else // L1_FF_MULTIBAND = 1 below
1928
1929 operative_radio_freq =
1930 l1_multiband_radio_freq_convert_into_operative_radio_freq(radio_freq_ctrl);
1931
1932 input_level =
1933 l1a_l1s_com.last_input_level[operative_radio_freq].input_level;
1934 lna_off =
1935 l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
1936 agc =
1937 Cust_get_agc_from_IL(radio_freq_ctrl,input_level >> 1, PWR_ID);
1938
1939 // Memorize the IL and LNA used for AGC setting.
1940 //l1pa_l1ps_com.cr_freq_list.used_il_lna[i] = l1a_l1s_com.last_input_level[radio_freq_ctrl - l1_config.std.radio_freq_index_offset];
1941 l1pa_l1ps_com.cr_freq_list.used_il_lna[i].il =
1942 l1a_l1s_com.last_input_level[operative_radio_freq].input_level;
1943 l1pa_l1ps_com.cr_freq_list.used_il_lna[i].lna =
1944 l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
1945
1946 #endif // #if (L1_FF_MULTIBAND == 0) else
1947
1948
1949 #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
1950 trace_fct(CST_CTRL_CR_MEAS, -1);
1951 #endif
1952
1953 #if(RF_FAM == 61) // Locosto DCO
1954 #if (PWMEAS_IF_MODE_FORCE == 0)
1955 cust_get_if_dco_ctl_algo(&dco_algo_ctl_pw_temp, &if_ctl, (UWORD8) L1_IL_VALID ,
1956 input_level,
1957 radio_freq_ctrl, if_threshold);
1958 #else
1959 if_ctl = IF_120KHZ_DSP;
1960 dco_algo_ctl_pw_temp = DCO_IF_0KHZ;
1961 #endif
1962
1963 dco_algo_ctl_pw |= ( (dco_algo_ctl_pw_temp & 0x03)<< (i*2));
1964 #endif
1965
1966
1967 // tpu pgm: 1 measurement only.
1968 l1dtpu_meas(radio_freq_ctrl,
1969 agc,
1970 lna_off,
1971 l1s.tpu_win,
1972 l1s.tpu_offset,INACTIVE
1973 #if(RF_FAM == 61)
1974 ,L1_AFC_SCRIPT_MODE
1975 ,if_ctl
1976 #endif
1977 );
1978
1979 // increment carrier counter for next measurement...
1980 if(++next_to_ctrl >= cr_list_size)
1981 next_to_ctrl = 0;
1982
1983 #if L2_L3_SIMUL
1984 #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET_NEIGH)
1985 buffer_trace(4, l1s.actual_time.fn, radio_freq_ctrl,
1986 l1s.tpu_win, 0);
1987 #endif
1988 #endif
1989
1990 // Increment tpu window identifier.
1991 l1s.tpu_win += (l1_config.params.rx_synth_load_split + PWR_LOAD);
1992
1993 } // End for(...nb_meas_to_perform)
1994
1995 #if(RF_FAM == 61)
1996 l1ddsp_load_dco_ctl_algo_pw(dco_algo_ctl_pw);
1997 #endif
1998
1999
2000 // Program DSP, in order to performed nb_meas_to_perform measures
2001 // Second argument specifies if a Rx burst will be received in this frame
2002 l1pddsp_meas_ctrl(nb_meas_to_perform, pw_position);
2003
2004 // Update d_debug timer
2005 l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
2006
2007
2008 // Flag measurement control.
2009 // **************************
2010
2011 // Set flag "ms_ctrl" to nb_meas_to_perform.
2012 // It will be used as 2 tdma delayed to trigger Read phase.
2013 l1pa_l1ps_com.cr_freq_list.ms_ctrl = nb_meas_to_perform;
2014
2015 // Flag DSP and TPU programmation.
2016 // ********************************
2017
2018 // Set "CTRL_MS" flag in the controle flag register.
2019 l1s.tpu_ctrl_reg |= CTRL_MS;
2020 l1s.dsp_ctrl_reg |= CTRL_MS;
2021
2022 // Update nbr_meas
2023 nbr_meas -= nb_meas_to_perform;
2024
2025 // Update remainig measurements to performed according meas done
2026 //remain_carrier -= nb_meas_to_perform;
2027
2028 } // End of test on is PBCCHS, FB/SB or BCCHN task active
2029 } //end ctrl
2030
2031 #if FF_L1_IT_DSP_USF
2032 } // if (l1ps_macs_com.usf_status != USF_AWAITED)
2033
2034 if (l1ps_macs_com.usf_status != USF_IT_DSP)
2035 {
2036 #endif
2037
2038 // If it's time, update time to next measures position and state
2039 // Two cases are considered: "pnp_period >= 1s" and "pnp_period < 1s"
2040
2041 if(schedule_trigger)
2042 {
2043 BOOL condition = FALSE;
2044
2045 schedule_trigger = FALSE;
2046
2047 // Compute time to next session of measures for "PNP period >= 1s" case
2048 if(l1pa_l1ps_com.pccch.pnp_period >= 216)
2049 {
2050 while(!condition)
2051 {
2052 switch(state)
2053 {
2054 case NULL_MEAS:
2055 {
2056 #if (GSM_IDLE_RAM != 1)
2057 // Check if memory for L1P_CR_MEAS_DONE msg is allocated
2058 if (cr_msg == NULL)
2059 {
2060 cr_msg = os_alloc_sig(sizeof(T_L1P_CR_MEAS_DONE));
2061 DEBUGMSG(status,NU_ALLOC_ERR)
2062 cr_msg->SignalCode = L1P_CR_MEAS_DONE;
2063 }
2064 #endif
2065
2066 if((l1pa_l1ps_com.pccch.time_to_pnp > ((866 * session_done) + time_to_4s)) &&
2067 (l1pa_l1ps_com.pccch.pnp_period >= 866))
2068 {
2069 state = TOTAL;
2070 time_to_wake_up = (433 + time_to_4s * session_done);
2071 condition = TRUE;
2072 }
2073 else
2074 {
2075 state = PCHTOTAL;
2076 time_to_wake_up = l1pa_l1ps_com.pccch.time_to_pnp;
2077 condition = TRUE;
2078 }
2079 }
2080 break;
2081
2082 case TOTAL:
2083 case PCHTOTAL:
2084 state = NULL_MEAS;
2085 break;
2086 }
2087 }
2088 } // End of "PNP period >= 1s" case
2089 else
2090 // Compute time to next session of measures for "PNP period < 1s" case
2091 {
2092 while(!condition)
2093 {
2094 switch(state)
2095 {
2096 case NULL_MEAS:
2097 {
2098 // Let's assume a small frequency list size
2099 // and a PNP period such that PM are performed
2100 // on first PPCH block and then stopped. PM activity
2101 // must be re-scheduled at the end of PPCH block.
2102 if((l1pa_l1ps_com.pccch.time_to_pnp < time_to_1s) && !(init_meas))
2103 {
2104 time_to_wake_up = l1pa_l1ps_com.pccch.time_to_pnp;
2105 schedule_trigger = TRUE;
2106 condition = TRUE;
2107 }
2108 else
2109 {
2110 #if (GSM_IDLE_RAM == 0)
2111 // Check if memory for L1P_CR_MEAS_DONE msg is allocated
2112 if (cr_msg == NULL)
2113 {
2114 cr_msg = os_alloc_sig(sizeof(T_L1P_CR_MEAS_DONE));
2115 DEBUGMSG(status,NU_ALLOC_ERR)
2116 cr_msg->SignalCode = L1P_CR_MEAS_DONE;
2117 }
2118 #endif
2119
2120 state = MEAS;
2121 time_to_wake_up = l1pa_l1ps_com.pccch.time_to_pnp;
2122 remain_carrier = (WORD8)cr_list_size;
2123 condition = TRUE;
2124 }
2125 }
2126 break;
2127
2128 case MEAS:
2129 {
2130 UWORD8 max_nbmeas;
2131 WORD16 tpu_win_rest;
2132 UWORD16 power_meas_split;
2133
2134 // Compute how many BP_SPLIT remains for cr list meas
2135 // Rem: we take into account the SYNTH load for 1st RX in next frame.
2136 // WARNING: only one RX activity is considered in next paging block !!!
2137 tpu_win_rest = FRAME_SPLIT - (RX_LOAD + l1_config.params.rx_synth_load_split);
2138
2139 power_meas_split = (l1_config.params.rx_synth_load_split + PWR_LOAD);
2140 max_nbmeas = 0;
2141
2142 while(tpu_win_rest >= power_meas_split)
2143 {
2144 max_nbmeas ++;
2145 tpu_win_rest -= power_meas_split;
2146 }
2147
2148 if (max_nbmeas > NB_MEAS_MAX_GPRS) max_nbmeas = NB_MEAS_MAX_GPRS;
2149
2150 // Update number of remaining carrier to measure.
2151 // Note: std.nbmeas provides max nbr of PM / TDMA
2152 remain_carrier -= 4 * max_nbmeas;
2153
2154 if(remain_carrier <= 0)
2155 state = NULL_MEAS;
2156 else
2157 {
2158 if((l1pa_l1ps_com.pccch.time_to_pnp >= time_to_1s) || !(session_done_1s))
2159 {
2160 state = MEASTOTAL;
2161 time_to_wake_up = 1;
2162 condition = TRUE;
2163 }
2164 else
2165 {
2166 time_to_wake_up = l1pa_l1ps_com.pccch.time_to_pnp;
2167 condition = TRUE;
2168 }
2169 }
2170 }
2171 break;
2172
2173 case MEASTOTAL:
2174 {
2175 #if (GSM_IDLE_RAM != 1)
2176 // Check if memory for L1P_CR_MEAS_DONE msg is allocated
2177 if (cr_msg == NULL)
2178 {
2179 cr_msg = os_alloc_sig(sizeof(T_L1P_CR_MEAS_DONE));
2180 DEBUGMSG(status,NU_ALLOC_ERR)
2181 cr_msg->SignalCode = L1P_CR_MEAS_DONE;
2182 }
2183 #endif
2184
2185 state = MEAS;
2186 time_to_wake_up = l1pa_l1ps_com.pccch.time_to_pnp;
2187 remain_carrier = (WORD8)cr_list_size;
2188 condition = TRUE;
2189 }
2190 break;
2191 }
2192 } // End of while
2193 } // End of else ("PNP period < 1s" case)
2194 } // End of if(schedule_trigger)
2195
2196 #if FF_L1_IT_DSP_USF
2197 } // if (l1ps_macs_com.usf_status != USF_IT_DSP)
2198
2199 if (l1ps_macs_com.usf_status != USF_AWAITED)
2200 {
2201 #endif
2202
2203 // Update time to next L1S task
2204 if((l1pa_l1ps_com.cr_freq_list.ms_ctrl) ||
2205 (l1pa_l1ps_com.cr_freq_list.ms_ctrl_d))
2206 {
2207 // Still some measurement results to get from DSP
2208 l1a_l1s_com.time_to_next_l1s_task = 0;
2209 }
2210 else
2211 {
2212 // No more measurements to read, next session of meas must
2213 // be at time_to_wake_up
2214 Select_min_time(time_to_wake_up, l1a_l1s_com.time_to_next_l1s_task);
2215 }
2216
2217 // Clear controlled flag pnp_ctrl.
2218 //-------------------------------
2219 l1pa_l1ps_com.cr_freq_list.pnp_ctrl = 0;
2220
2221 // C W R pipeline management.
2222 //---------------------------
2223 l1pa_l1ps_com.cr_freq_list.ms_ctrl_dd = l1pa_l1ps_com.cr_freq_list.ms_ctrl_d;
2224 l1pa_l1ps_com.cr_freq_list.ms_ctrl_d = l1pa_l1ps_com.cr_freq_list.ms_ctrl;
2225 l1pa_l1ps_com.cr_freq_list.ms_ctrl = 0;
2226
2227 // C W R pipeline management.
2228 //---------------------------
2229 {
2230 UWORD8 i;
2231
2232 for(i=0; i<NB_MEAS_MAX_GPRS; i++)
2233 {
2234 l1pa_l1ps_com.cr_freq_list.used_il_lna_dd[i] = l1pa_l1ps_com.cr_freq_list.used_il_lna_d[i];
2235 l1pa_l1ps_com.cr_freq_list.used_il_lna_d [i] = l1pa_l1ps_com.cr_freq_list.used_il_lna [i];
2236 }
2237 }
2238
2239 #if FF_L1_IT_DSP_USF
2240 } // if (l1ps_macs_com.usf_status != USF_AWAITED)
2241 #endif
2242 } // End of if: P_CRMS_MEAS enable and associated semaphore = 0.
2243
2244 }
2245
2246 //#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END
2247 #endif
2248
2249
2250 #if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
2251 //#pragma DUPLICATE_FOR_INTERNAL_RAM_START
2252
2253 /*-------------------------------------------------------*/
2254 /* l1ps_transfer_meas_manager() */
2255 /*-------------------------------------------------------*/
2256 /* */
2257 /* Description: */
2258 /* ------------ */
2259 /* Whilst in Packet Transfer mode, MS shall continuously */
2260 /* monitor all the BCCH carriers as indicated by a */
2261 /* frequency list (BA(GPRS), Network Control frequency */
2262 /* list and Extended list) and the BCCH carrier of the */
2263 /* serving cell. Received signal level is used to monitor*/
2264 /* the specified neighbour BCCH carriers. */
2265 /* */
2266 /* Receive signal level measurement samples shall be */
2267 /* performed according to the following conditions: */
2268 /* */
2269 /* 1) At least 1 measure shall be done every TDMA, */
2270 /* 2) Up to 2 TDMA frames per PDCH multiframe may be */
2271 /* omitted if required for BSIC decoding, */
2272 /* 3) Running average value (RLA_P) is based on a 5s */
2273 /* period and includes at least 5 measure samples, */
2274 /* 4) The same number of measures shall be taken for all */
2275 /* BCCH carriers except: */
2276 /* i) For the Serving Cell, where at least 6 measures */
2277 /* shall be taken per MF52, */
2278 /* ii) if PC_MEAS_CHAN indicates that power control */
2279 /* measures shall be made on BCCH. */
2280 /* 5) Measures used to compute RLA_P shall as far as */
2281 /* possible be uniformly distributed, */
2282 /*-------------------------------------------------------*/
2283 void l1ps_transfer_meas_manager()
2284 {
2285 UWORD8 IL_for_rxlev;
2286
2287 static xSignalHeaderRec *tcr_msg = NULL;
2288
2289 static BOOL tcr_meas_removed = FALSE;
2290
2291 #define tcr_next_to_read l1pa_l1ps_com.tcr_freq_list.tcr_next_to_read
2292 #define tcr_next_to_ctrl l1pa_l1ps_com.tcr_freq_list.tcr_next_to_ctrl
2293 #define last_stored_tcr_to_read l1pa_l1ps_com.tcr_freq_list.last_stored_tcr_to_read
2294
2295
2296 #if FF_L1_IT_DSP_USF
2297 if (l1ps_macs_com.usf_status != USF_IT_DSP)
2298 {
2299 #endif
2300
2301 // Test if task is disabled and cr_msg != NULL, then de-allocate memory
2302 if(tcr_msg != NULL)
2303 {
2304 if(!(l1pa_l1ps_com.l1ps_en_meas & P_TCRMS_MEAS) &&
2305 !(l1pa_l1ps_com.meas_param & P_TCRMS_MEAS))
2306 {
2307 // Neighbour measurement process has been stopped by L3
2308 // Deallocate memory for the received message if msg not forwarded to L3.
2309 // ----------------------------------------------------------------------
2310 os_free_sig(tcr_msg);
2311 DEBUGMSG(status,NU_DEALLOC_ERR)
2312
2313 tcr_msg = NULL;
2314 }
2315 }
2316
2317 #if FF_L1_IT_DSP_USF
2318 } // if (l1ps_macs_com.usf_status != USF_IT_DSP)
2319 #endif
2320
2321 if(l1pa_l1ps_com.l1ps_en_meas & P_TCRMS_MEAS)
2322 {
2323
2324 #if FF_L1_IT_DSP_USF
2325 if (l1ps_macs_com.usf_status != USF_IT_DSP)
2326 {
2327 #endif
2328
2329 // Increment l1pa_l1ps_com.tcr_freq_list.cres_meas_report
2330 if(++l1pa_l1ps_com.tcr_freq_list.cres_meas_report > 103)
2331 l1pa_l1ps_com.tcr_freq_list.cres_meas_report = 0;
2332
2333 // Check if it's first time, Neighbour Measurement process is launched.
2334 // Then initialize fn_report counter and reset semaphore.
2335 if(l1pa_l1ps_com.meas_param & P_TCRMS_MEAS)
2336 {
2337 // Initialize counter used to report measurements
2338 l1pa_l1ps_com.tcr_freq_list.cres_meas_report = 0;
2339
2340 // Reset Neighbour Measurements semaphore
2341 l1pa_l1ps_com.meas_param &= P_TCRMS_MEAS_MASK;
2342 }
2343
2344 //====================================================
2345 // RESET MEASUREMENT MACHINES WHEN SYNCHRO EXECUTED.
2346 //====================================================
2347 if(l1s.tpu_ctrl_reg & CTRL_SYNC)
2348 // SYNCHRO task has been executed.
2349 // -> Reset measures made on serving cell,
2350 // -> Rewind pointer used in Neighbour Cell measurement,
2351 // -> return.
2352 {
2353
2354 // Reset Neighbour Cell measurement machine.
2355 // Rewind "next_to_ctrl" counter to come back to the next carrier to
2356 // measure.
2357 tcr_next_to_ctrl = tcr_next_to_read;
2358
2359 // Reset flags.
2360 l1pa_l1ps_com.tcr_freq_list.ms_ctrl = 0;
2361 l1pa_l1ps_com.tcr_freq_list.ms_ctrl_d = 0;
2362 l1pa_l1ps_com.tcr_freq_list.ms_ctrl_dd = 0;
2363
2364 // Reset measures made on beacon frequency.
2365 l1pa_l1ps_com.tcr_freq_list.beacon_meas = 0;
2366 }
2367
2368 // *******************
2369 // Message Allocation
2370 // *******************
2371 // The reporting message must be allocated before READ phase.
2372
2373 if(l1pa_l1ps_com.tcr_freq_list.cres_meas_report == 2)
2374 {
2375 // Memory allocation
2376 if (tcr_msg == NULL)
2377 {
2378 // alloc L1P_TCR_MEAS_DONE message...
2379 tcr_msg = os_alloc_sig(sizeof(T_MPHP_TCR_MEAS_IND));
2380 DEBUGMSG(status,NU_ALLOC_ERR)
2381 tcr_msg->SignalCode = L1P_TCR_MEAS_DONE;
2382 }
2383
2384 l1pa_l1ps_com.tcr_freq_list.first_pass_flag = TRUE;
2385 }
2386
2387 //------------------------------------------------------
2388 // READ and CTRL phase of the Neighbour Measurement task
2389 //------------------------------------------------------
2390
2391 //-----------
2392 // READ phase
2393 //-----------
2394
2395 // Test if Measurment has been removed (ms_ctrl_d forced to 0) during
2396 // previous frame, then switch DSP read page.
2397 if (tcr_meas_removed)
2398 {
2399 l1s_dsp_com.dsp_r_page_used = TRUE;
2400 tcr_meas_removed = FALSE;
2401 }
2402
2403 // Background measurements....
2404 // A measurement controle was performed 2 tdma earlier, read result now!!
2405 if(l1pa_l1ps_com.tcr_freq_list.ms_ctrl_dd != 0)
2406 {
2407 UWORD16 radio_freq_read;
2408 UWORD8 pm_read;
2409
2410 #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
2411 trace_fct(CST_READ_TCR_MEAS, (UWORD32)(-1));
2412 #endif
2413
2414 l1_check_com_mismatch(TCR_MEAS_ID);
2415
2416 // When a read is performed, we set dsp_r_page_used flag to
2417 // switch the read page
2418 l1s_dsp_com.dsp_r_page_used = TRUE;
2419
2420 // Read power measurement result from DSP/MCU GPRS interface
2421 l1pddsp_meas_read(l1pa_l1ps_com.tcr_freq_list.ms_ctrl_dd, &pm_read);
2422
2423 l1_check_pm_error(pm_read, TCR_MEAS_ID);
2424
2425 radio_freq_read = l1pa_l1ps_com.cres_freq_list.alist->freq_list[tcr_next_to_read];
2426
2427 // Get Input level corresponding to the used IL and pm result.
2428 IL_for_rxlev = l1pctl_pgc(((UWORD8) (pm_read)),
2429 l1pa_l1ps_com.tcr_freq_list.used_il_lna_dd.il,
2430 l1pa_l1ps_com.tcr_freq_list.used_il_lna_dd.lna,
2431 radio_freq_read);
2432
2433 #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
2434 RTTL1_FILL_MON_MEAS(pm_read, IL_for_rxlev, TCR_MEAS_ID, radio_freq_read)
2435 #endif
2436
2437
2438 if(l1pa_l1ps_com.tcr_freq_list.first_pass_flag)
2439 {
2440 // Fill reporting message: Store RXLEV
2441 ((T_L1P_TCR_MEAS_DONE*)(tcr_msg->SigP))->acc_level[tcr_next_to_read] =
2442 l1s_encode_rxlev(IL_for_rxlev);
2443
2444 ((T_L1P_TCR_MEAS_DONE*)(tcr_msg->SigP))->acc_nbmeas[tcr_next_to_read] = 1;
2445 }
2446 else
2447 {
2448 // Fill reporting message: Accumulate RXLEV
2449 ((T_L1P_TCR_MEAS_DONE*)(tcr_msg->SigP))->acc_level[tcr_next_to_read] +=
2450 l1s_encode_rxlev(IL_for_rxlev);
2451
2452 ((T_L1P_TCR_MEAS_DONE*)(tcr_msg->SigP))->acc_nbmeas[tcr_next_to_read] += 1;
2453
2454 }
2455
2456 // Increment "next_to_read" field for next measurement...
2457 if(++tcr_next_to_read >= l1pa_l1ps_com.cres_freq_list.alist->nb_carrier)
2458 {
2459 tcr_next_to_read = 0;
2460 }
2461
2462 // First pass has been completed on all BA list, reset "first_pass_flag"
2463 if(tcr_next_to_read == last_stored_tcr_to_read)
2464 l1pa_l1ps_com.tcr_freq_list.first_pass_flag = FALSE;
2465
2466 } // End of READ phase
2467
2468
2469 // ************************
2470 // Reporting & List Update
2471 // ************************
2472 if(l1pa_l1ps_com.tcr_freq_list.cres_meas_report == 1)
2473 {
2474 if(tcr_msg != NULL)
2475 {
2476 // Fill TCR list identifier field.
2477 ((T_L1P_TCR_MEAS_DONE*)(tcr_msg->SigP))->list_id = l1pa_l1ps_com.cres_freq_list.alist->list_id;
2478
2479 // send L1P_TCR_MEAS_DONE message...
2480 os_send_sig(tcr_msg, L1C1_QUEUE);
2481 DEBUGMSG(status,NU_SEND_QUEUE_ERR)
2482
2483 // Reset pointer for debugg.
2484 tcr_msg = NULL;
2485 }
2486
2487 // Update Frequency list pointer and reset new list flag
2488 if(l1pa_l1ps_com.tcr_freq_list.new_list_present)
2489 {
2490 //Update Frequency list pointer
2491 l1pa_l1ps_com.cres_freq_list.alist = l1pa_l1ps_com.cres_freq_list.flist;
2492
2493 // Test if a Meas has been controlled in previous frame
2494 // Then set tcr_meas_removed flag in order to switch DSP read page in next frame
2495 if(l1pa_l1ps_com.tcr_freq_list.ms_ctrl_d != 0)
2496 {
2497 tcr_meas_removed = TRUE;
2498 }
2499
2500 // Reset pointer
2501 tcr_next_to_ctrl = 0;
2502 tcr_next_to_read = 0;
2503 l1pa_l1ps_com.tcr_freq_list.ms_ctrl_d = 0;
2504
2505 // Reset New list flag
2506 l1pa_l1ps_com.tcr_freq_list.new_list_present = FALSE;
2507 }
2508
2509 // While reporting, save Last "tcr_next_to_read" value to know when reset "first_pass_flag"
2510 last_stored_tcr_to_read = tcr_next_to_read;
2511 }
2512
2513 //-----------
2514 // CTRL phase
2515 //-----------
2516
2517 // CTRL phase is divided in two parts according measures allocated by MACS.
2518 // CTRL phase must then be exported in CTRL PDTCH function except for the Idle
2519 // frame where no PDTCH are programmed.
2520 // A measure can be performed during the idle frame, only if FB/SB/PTCCH
2521 // and Interference Measurement task is not active.
2522 if(!(l1pa_l1ps_com.meas_param & P_TCRMS_MEAS))
2523 {
2524 if((l1s.actual_time.t2 == 24) || (l1s.actual_time.t2 == 11))
2525 {
2526 if(l1s.forbid_meas == 0)
2527 {
2528 #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
2529 trace_fct(CST_CTRL_TCR_MEAS_2,(UWORD32)(-1));
2530 #endif
2531
2532 l1ps_tcr_ctrl(0);
2533 }
2534 }
2535 }
2536
2537 #if FF_L1_IT_DSP_USF
2538 } // if (l1ps_macs_com.usf_status != USF_IT_DSP)
2539 #endif
2540
2541 #if FF_L1_IT_DSP_USF
2542 if (l1ps_macs_com.usf_status != USF_AWAITED)
2543 {
2544 #endif
2545
2546 // Pipe Manager
2547 l1pa_l1ps_com.tcr_freq_list.ms_ctrl_dd = l1pa_l1ps_com.tcr_freq_list.ms_ctrl_d;
2548 l1pa_l1ps_com.tcr_freq_list.ms_ctrl_d = l1pa_l1ps_com.tcr_freq_list.ms_ctrl;
2549 l1pa_l1ps_com.tcr_freq_list.ms_ctrl = 0;
2550
2551 #if FF_L1_IT_DSP_USF
2552 } // if (l1ps_macs_com.usf_status != USF_AWAITED)
2553 #endif
2554
2555 } // End of if(l1pa_l1ps_com.l1ps_en_meas & P_TCRMS_MEAS)
2556
2557 /*****************************/
2558 /* PC_MEAS_CHAN measurements */
2559 /*****************************/
2560
2561 // If PC_MEAS_CHAN = 1, then BCCH serving cell carrier must be
2562 // measured at least 6 times per MF52.
2563 // CTRL of Serving Cell Carrier is performed two TDMA earlier.
2564 if(l1pa_l1ps_com.transfer.aset->pc_meas_chan == FALSE)
2565 {
2566
2567 #if FF_L1_IT_DSP_USF
2568 if (l1ps_macs_com.usf_status != USF_IT_DSP)
2569 {
2570 #endif
2571
2572 if(l1s.tpu_ctrl_reg & CTRL_SYNC)
2573 // SYNCHRO task has been executed.
2574 {
2575 l1ps.pc_meas_chan_ctrl = FALSE;
2576 }
2577
2578 //-----------
2579 // READ phase
2580 //-----------
2581
2582 if ((l1ps.pc_meas_chan_ctrl == TRUE) &&
2583 ((l1s.actual_time.t2 == 3) || (l1s.actual_time.t2 == 11)
2584 || (l1s.actual_time.t2 == 20)))
2585 {
2586 UWORD8 pm_read;
2587
2588 l1_check_com_mismatch(PC_MEAS_CHAN_ID);
2589
2590 // When a read is performed, we set dsp_r_page_used flag to
2591 // switch the read page
2592 l1s_dsp_com.dsp_r_page_used = TRUE;
2593
2594 // Read power measurement result from DSP/MCU GPRS interface
2595 l1pddsp_meas_read(1, &pm_read);
2596
2597
2598 #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
2599 trace_fct(CST_READ_PC_MEAS_CHAN,(UWORD32)(-1));
2600 #endif
2601
2602 l1_check_pm_error(pm_read, PC_MEAS_CHAN_ID);
2603
2604 l1ps.pc_meas_chan_ctrl = FALSE;
2605
2606 // Get Input level corresponding to the used IL and pm result.
2607 IL_for_rxlev = l1pctl_pgc(((UWORD8 )(pm_read)),
2608 l1pa_l1ps_com.tcr_freq_list.used_il_lna_dd.il,
2609 l1pa_l1ps_com.tcr_freq_list.used_il_lna_dd.lna,
2610 l1a_l1s_com.Scell_info.radio_freq);
2611
2612 #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
2613 RTTL1_FILL_MON_MEAS(pm_read, IL_for_rxlev, PC_MEAS_CHAN_ID, l1a_l1s_com.Scell_info.radio_freq)
2614 #endif
2615
2616 if (l1a_l1s_com.mode == PACKET_TRANSFER_MODE)
2617 // Store RXLEV, before to pass it to maca_power_control() function..
2618 l1pa_l1ps_com.tcr_freq_list.beacon_meas = l1s_encode_rxlev(IL_for_rxlev);
2619 }
2620
2621 //-----------
2622 // CTRL phase
2623 //-----------
2624
2625 // In two phase access, PC_MEAS_CHAN measurements can be done...
2626 if((l1a_l1s_com.l1s_en_task[SINGLE] == TASK_ENABLED) &&
2627 (l1pa_l1ps_com.transfer.aset->allocated_tbf == TWO_PHASE_ACCESS))
2628 if (l1s.task_status[NP].current_status != ACTIVE) // avoid conflict with Normal Paging
2629 if (l1s.task_status[EP].current_status != ACTIVE) // avoid conflict with Extended Paging
2630 {
2631 // Measurement on the beacon
2632 if((l1s.actual_time.t2 == 1) || (l1s.actual_time.t2 == 9) ||
2633 (l1s.actual_time.t2 == 18))
2634 {
2635 // Measurement programming
2636 // ts 4 is specified for DSP interface ONLY because the power activity
2637 // must be programmed after RX and/or TX activity (no multislot)
2638 #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
2639 trace_fct(CST_CTRL_PC_MEAS_CHAN, (UWORD32)(-1));
2640 #endif
2641
2642 l1ps_bcch_meas_ctrl(4);
2643 }
2644 }
2645
2646 #if FF_L1_IT_DSP_USF
2647 } // if (l1ps_macs_com.usf_status != USF_IT_DSP)
2648 #endif
2649
2650 } // End of Meas made on BCCH serving cell
2651
2652 #if FF_L1_IT_DSP_USF
2653 if (l1ps_macs_com.usf_status != USF_AWAITED)
2654 {
2655 #endif
2656
2657 if((l1pa_l1ps_com.l1ps_en_meas & P_TCRMS_MEAS) || (l1ps.pc_meas_chan_ctrl == TRUE))
2658 {
2659 // C W R pipeline management.
2660 //---------------------------
2661 l1pa_l1ps_com.tcr_freq_list.used_il_lna_dd = l1pa_l1ps_com.tcr_freq_list.used_il_lna_d;
2662 l1pa_l1ps_com.tcr_freq_list.used_il_lna_d = l1pa_l1ps_com.tcr_freq_list.used_il_lna;
2663 }
2664
2665 #if FF_L1_IT_DSP_USF
2666 } // if (l1ps_macs_com.usf_status != USF_AWAITED)
2667 #endif
2668
2669 }
2670 //#pragma DUPLICATE_FOR_INTERNAL_RAM_END
2671 #endif // MOVE_IN_INTERNAL_RAM
2672
2673 //#pragma DUPLICATE_FOR_INTERNAL_RAM_START
2674 #endif
2675 //#pragma DUPLICATE_FOR_INTERNAL_RAM_END