comparison chipsetsw/layer1/cmacs/macs.c @ 338:a4a1c5bb4be6

macs.c: initial import from LoCosto source
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 29 Oct 2017 18:54:50 +0000
parents 6814a6bced4f
children 3c3b9bdd206b
comparison
equal deleted inserted replaced
337:34166dff7280 338:a4a1c5bb4be6
1 /* dummy C source file */ 1 /************* Revision Control System Header *************
2 * GSM Layer 1 software
3 * MACS.C
4 *
5 * Filename macs.c
6 * Copyright 2003 (C) Texas Instruments
7 *
8 ************* Revision Control System Header *************/
9
10
11 //---Configuration flags---------------------------------------------------
12
13 #define TFI_FILTERING 1 // TFI FILTERING activated if set to 1
14 //-------------------------------------------------------------------------
15
16
17 #include <stdlib.h>
18 #include <stdio.h>
19
20 #include "l1_macro.h"
21 #include "l1_confg.h"
22
23 #if L1_GPRS
24
25 #include "l1_types.h"
26 #include "l1_const.h"
27
28 #if TESTMODE
29 #include "l1tm_defty.h"
30 #include "l1tm_varex.h"
31 #endif
32 #if (AUDIO_TASK == 1)
33 #include "l1audio_const.h"
34 #include "l1audio_cust.h"
35 #include "l1audio_defty.h"
36 #endif
37 #if (L1_GTT == 1)
38 #include "l1gtt_const.h"
39 #include "l1gtt_defty.h"
40 #endif
41 #if (L1_MP3 == 1)
42 #include "l1mp3_defty.h"
43 #endif
44 #if (L1_MIDI == 1)
45 #include "l1midi_defty.h"
46 #endif
47 #include "l1_defty.h"
48 #include "l1_varex.h"
49 #include "l1_signa.h"
50
51 #include "l1p_cons.h"
52 #include "l1p_msgt.h"
53 #include "l1p_deft.h"
54 #include "l1p_vare.h"
55 #include "l1p_sign.h"
56
57 #include "l1tm_proto.h"
58
59 #include "macs_def.h"
60 #include "macs_cst.h"
61 #include "macs_var.h"
62
63 #if FF_TBF
64 #include "l1_trace.h"
65 #if (CODE_VERSION == SIMULATION)
66 #include "sim_cons.h"
67 #include "sim_def.h"
68 #include "sim_var.h"
69 #endif
70 #endif
71 /**********************************************************/
72 /* MACS-S Prototypes */
73 /**********************************************************/
74
75 void l1ps_macs_meas (void); // Measurement gap processing
76 void l1ps_macs_header_decoding (UWORD8 rx_no,
77 UWORD8 *tfi_result,
78 UWORD8 *pr); // MAC header decoding
79 void l1ps_macs_read (UWORD8 pr_table[8]); // MAC-S control tasks processing
80 void l1ps_macs_ctrl (void); // MAC-S read tasks processing
81 void l1ps_macs_init (void); // MAC-S initialization
82
83 #if FF_TBF
84 void l1ps_macs_rlc_uplink_info (void);
85 #endif
86
87 /**********************************************************/
88 /* EXTERNAL Prototypes */
89 /**********************************************************/
90
91 void l1pddsp_transfer_mslot_ctrl(UWORD8 burst_nb,
92 UWORD8 dl_bitmap,
93 UWORD8 ul_bitmap,
94 UWORD8 *usf_table,
95 UWORD8 mac_mode,
96 UWORD8 *ul_buffer_index,
97 UWORD8 tsc,
98 UWORD16 radio_freq,
99 UWORD8 synchro_timeslot,
100 #if FF_L1_IT_DSP_USF
101 UWORD8 dsp_usf_interrupt
102 #else
103 UWORD8 usf_vote_enable
104 #endif
105 );
106
107 /* RLC interface for uplink RLC/MAC blocks */
108 /*-----------------------------------------*/
109
110 void rlc_uplink(
111 UWORD8 assignment_id,
112 UWORD8 tx_data_no, // Number of timeslot that can be used
113 // for uplink data block transfer
114 UWORD32 fn, // Next frame number
115 UWORD8 timing_advance_value, // Timing advance (255 if unknown)
116 API *ul_poll_response, // Pointer on a_pu_gprs (NDB): poll response blocks
117 API *ul_data, // Pointer on a_du_gprs (NDB): uplink data blocks
118 BOOL allocation_exhausted // Set to 1 if fixed allocation exhausted
119 );
120
121 #if TESTMODE
122 void l1tm_rlc_uplink(UWORD8 tx, API *ul_data);
123 #endif
124
125 /* RLC interface for downlink RLC/MAC blocks */
126 /*-------------------------------------------*/
127 #if FF_TBF
128
129 void rlc_downlink_data(
130 UWORD8 assignment_id,
131 UWORD32 fn, // Actual frame number
132 API *dl // Pointer on a_dd_gprs (NDB): downlink blocks
133 );
134 void rlc_uplink_info(
135 UWORD8 assignment_id,
136 UWORD32 fn,
137 UWORD8 rlc_blocks_sent, // Number of uplink blocks that was transmitted
138 // during the last block period
139 UWORD8 last_poll_response // Status of the poll responses of
140 ); // the last block period
141
142 UWORD8 rlc_downlink_copy_buffer(UWORD8 isr);
143
144
145 #else
146
147 void rlc_downlink(
148 UWORD8 assignment_id,
149 UWORD32 fn, // Actual frame number
150 API *dl, // Pointer on a_dd_gprs (NDB): downlink blocks
151 UWORD8 rlc_blocks_sent, // Number of uplink blocks that was transmitted
152 // during the last block period
153 UWORD8 last_poll_response // Status of the poll responses of
154 // the last block period
155 );
156
157 #endif
158
159 #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
160 #include "l1_trace.h"
161 #endif
162
163
164 #if FF_TBF
165 #include <stddef.h>
166
167 #if (CODE_VERSION == SIMULATION)
168 API* const A_DD_XGPRS[1][4] =
169 {
170 {&buf.ndb_gprs.a_dd_gprs[0][0], &buf.ndb_gprs.a_dd_gprs[1][0], &buf.ndb_gprs.a_dd_gprs[2][0], &buf.ndb_gprs.a_dd_gprs[3][0]},
171 };
172
173 API* const A_DU_XGPRS[1][4] =
174 {
175 {&buf.ndb_gprs.a_du_gprs[0][0], &buf.ndb_gprs.a_du_gprs[1][0], &buf.ndb_gprs.a_du_gprs[2][0], &buf.ndb_gprs.a_du_gprs[3][0]}
176 };
177
178 #else
179 API* const A_DD_XGPRS[1][4] =
180 {
181 {
182 (API*)(NDB_ADR_GPRS + offsetof(T_NDB_MCU_DSP_GPRS, a_dd_gprs[0][0])),
183 (API*)(NDB_ADR_GPRS + offsetof(T_NDB_MCU_DSP_GPRS, a_dd_gprs[1][0])),
184 (API*)(NDB_ADR_GPRS + offsetof(T_NDB_MCU_DSP_GPRS, a_dd_gprs[2][0])),
185 (API*)(NDB_ADR_GPRS + offsetof(T_NDB_MCU_DSP_GPRS, a_dd_gprs[3][0]))
186 }
187 };
188
189 API* const A_DU_XGPRS[1][4] =
190 {
191 {
192 (API*)(NDB_ADR_GPRS + offsetof(T_NDB_MCU_DSP_GPRS,a_du_gprs[0][0])),
193 (API*)(NDB_ADR_GPRS + offsetof(T_NDB_MCU_DSP_GPRS,a_du_gprs[1][0])),
194 (API*)(NDB_ADR_GPRS + offsetof(T_NDB_MCU_DSP_GPRS,a_du_gprs[2][0])),
195 (API*)(NDB_ADR_GPRS + offsetof(T_NDB_MCU_DSP_GPRS,a_du_gprs[3][0]))
196 }
197 };
198 #endif
199
200 #endif
201 /*-----------------------------------------------------------*/
202 /* l1ps_macs_init() */
203 /*-----------------------------------------------------------*/
204 /* Parameters: */
205 /* */
206 /* Return: */
207 /* */
208 /* Description: This function initializes MAC-S variables */
209 /* and must be called before the first call */
210 /* of MAC-S */
211 /*-----------------------------------------------------------*/
212 void l1ps_macs_init(void)
213 {
214 UWORD8 i;
215
216 #if FF_TBF
217 macs.dl_buffer_index = INVALID;
218 for (i=0;i<NBR_SHARED_BUFFER_RLC;i++)
219 macs.rlc_dbl_buffer[i].d_rlcmac_rx_no_gprs = 0xff;
220 #endif
221 /* General TBF parameters processed by MAC-S */
222 /*********************************************/
223
224 macs.sti_block_id = 0;
225
226 /* Ressources allocated by MAC-S */
227 /*********************************************/
228
229 macs.rx_allocation = 0;
230 macs.tx_allocation = 0;
231 macs.tx_prach_allocation = 0;
232 macs.tx_data = 0;
233 macs.pwr_allocation = 0xff;
234 macs.last_rx_alloc = 0;
235
236 #if FF_L1_IT_DSP_USF
237 macs.dsp_usf_interrupt = 0;
238 #endif
239
240 macs.rx_blk_period = NO_DL_BLK;
241 macs.rlc_blocks_sent = 0;
242 macs.rx_no = 0;
243 macs.last_poll_response = 0;
244
245 macs.usf_good = 0;
246 macs.usf_vote_enable = 0;
247 macs.tra_gap = 8;
248 macs.fix_alloc_exhaust = FALSE;
249 macs.next_usf_mon_block[0] = macs.next_usf_mon_block[1] = 0;
250
251 for (i = 0; i < TS_NUMBER; i ++)
252 {
253 macs.ul_buffer_index[i] = INVALID;
254 }
255 #if L1_EDA
256 for (i = 0; i < 4; i++)
257 {
258 macs.monitored_ts[i] = INVALID;
259 }
260 macs.rx_monitored = 0;
261 macs.last_rx_monitored = 0;
262 macs.lowest_poll_ts = INVALID;
263 #endif
264
265 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
266 // Reset PDTCH trace structure
267 for(i=0; i<8; i++)
268 {
269 trace_info.pdtch_trace.dl_status[i] = 0;
270 trace_info.pdtch_trace.ul_status[i] = 0;
271 trace_info.pdtch_trace.blk_status = 0;
272 }
273 #endif
274
275 } /* End of l1ps_macs_init */
276
277 /*-----------------------------------------------------------*/
278 /* l1ps_macs_ctrl() */
279 /*-----------------------------------------------------------*/
280 /* Parameters:global l1ps_macs_com changed */
281 /* global l1s unchanged */
282 /* global l1a_l1s_com unchanged */
283 /* global l1ps_dsp_com changed */
284 /* */
285 /* Return: */
286 /* */
287 /* Description: MAC_S manages the timeslot allocation for */
288 /* downlink and uplink transfer and assign a */
289 /* measurement gap according to the MS class, */
290 /* the frame number when it's called and the */
291 /* allocation information given by Layer 1. */
292 /* It also program the corresponding tasks on */
293 /* the DSP and asks the RLC layer for uplink */
294 /* blocks */
295 /*-----------------------------------------------------------*/
296 void l1ps_macs_ctrl(void)
297 {
298 #define NDB_PTR l1ps_dsp_com.pdsp_ndb_ptr
299 #define SET_PTR l1pa_l1ps_com.transfer.aset
300
301 #if MACS_STATUS
302 // No error
303 l1ps_macs_com.macs_status.nb = 0;
304 #endif
305
306 /***********************************************************/
307 /* USF values updating in dynamic mode (first frames of */
308 /* block periods) */
309 /***********************************************************/
310
311 if ((SET_PTR->allocated_tbf == UL_TBF) || (SET_PTR->allocated_tbf == BOTH_TBF))
312 {
313 #if L1_EDA
314 if ((SET_PTR->mac_mode == DYN_ALLOC) || (SET_PTR->mac_mode == EXT_DYN_ALLOC))
315 #else
316 if (SET_PTR->mac_mode == DYN_ALLOC)
317 #endif
318 {
319 // Test if the USF must be read in the current frame
320 // Concern the first frames of each block period (useful when
321 // some USF values weren't valid the frame before)
322 // FN 13
323 // 0 1 2 3 4 5 6 7 8 9 10 11 12
324 // ----------------------------------------------------------
325 // || B0 || B1 || B2 || I ||
326 // || | | | || | X | | || | X | | || ||
327 // ----------------------------------------------------------
328 // X:USF Reading
329
330 #if FF_L1_IT_DSP_USF
331 if (l1ps_macs_com.usf_status == USF_IT_DSP)
332 #else
333 if ( (l1s.next_time.fn_mod13 == 5)
334 || (l1s.next_time.fn_mod13 == 9))
335 #endif
336 {
337 // USF values are read
338 // Uplink timeslots whose USF was INVALID the frame before are de-allocated
339 // if their USF value is now BAD
340
341 UWORD8 tn;
342
343 // Reading of the d_usf_updated_gprs value
344 API usf_updated = NDB_PTR->d_usf_updated_gprs;
345
346 #if !L1_EDA
347 // For each timeslot that can be allocated in uplink...
348 for (tn = macs.first_monitored_ts; tn <= macs.last_monitored_ts; tn ++)
349 {
350 // If USF vote was enabled on this timeslot
351 if(macs.usf_vote_enable & (MASK_SLOT0 >> tn))
352 {
353 // Clear the USF vote flag
354 macs.usf_vote_enable &= ~(MASK_SLOT0 >> tn);
355
356 // Read USF value
357 if (((usf_updated >> ((MAX_TS_NB - tn) * 2)) & MASK_2SLOTS) == USF_GOOD)
358 {
359 // This timeslot is valid and good
360 macs.usf_good |= (UWORD8) (MASK_SLOT0 >> (tn + 3));
361 macs.next_usf_mon_block[tn - macs.first_monitored_ts] = l1s.next_time.block_id + USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity];
362 }
363 else
364 {
365 // This timeslot is bad or invalid
366 // If the slot was allocated for data
367 if (macs.tx_data & (MASK_SLOT0 >> (tn + RXTX_DELAY)))
368 {
369 // rlc_blocks_sent decremented
370 macs.rlc_blocks_sent --;
371
372 #if FF_L1_IT_DSP_USF
373 // If next timeslot is also a data block:
374 // Shift data block to next TX opportunity. For MS class 12
375 // with dynamic allocation, 2 TX data max and they are
376 // contiguous (optimization).
377 if (macs.tx_data & (MASK_SLOT0 >> (tn + 1 + RXTX_DELAY)))
378 {
379 macs.ul_buffer_index[tn + 1 + RXTX_DELAY] = macs.ul_buffer_index[tn + RXTX_DELAY];
380
381 }
382
383 // Cancel burst
384 macs.ul_buffer_index[tn + RXTX_DELAY] = INVALID;
385
386 #endif // FF_L1_IT_DSP_USF
387
388 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
389 if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
390 trace_info.pdtch_trace.ul_status[tn + RXTX_DELAY] = 0;
391 #endif
392
393 #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
394 RTTL1_FILL_MACS_STATUS(TX_CANCELLED_USF, tn)
395 #endif
396 }
397 }
398 } // End if "USF vote enabled on this timeslot"
399 } // End for
400
401 /* Uplink resources de-allocated by the DSP are de-allocated by MAC-S */
402 macs.tx_allocation &= (UWORD8) (macs.usf_good | ~macs.tx_data);
403 macs.tx_data &= (UWORD8) (macs.usf_good | ~macs.tx_data);
404 #else //#if !L1_EDA
405 UWORD8 i = 0;
406
407 //for all timeslots that need to be monitored
408 while ((macs.monitored_ts[i] != INVALID) && (i <= 3))
409 {
410 // If USF vote was enabled on this timeslot
411 if(macs.usf_vote_enable & (MASK_SLOT0 >> macs.monitored_ts[i]))
412 {
413 // Clear the USF vote flag
414 macs.usf_vote_enable &= ~(MASK_SLOT0 >> macs.monitored_ts[i]);
415
416 // Read USF value
417 if ((((usf_updated >> ((MAX_TS_NB - macs.monitored_ts[i]) * 2)) & MASK_2SLOTS) == USF_GOOD)
418 && (macs.last_rx_monitored & (MASK_SLOT0 >> macs.monitored_ts[i])))
419 {
420 if (SET_PTR->mac_mode == EXT_DYN_ALLOC)
421 {
422 //RX timeslots to monitor have to be updated upon USF status receipt (only first ts with
423 //good USF has to be considered)
424 if ((macs.monitored_ts[i] <= macs.lowest_poll_ts) ||
425 ((MASK_SLOT0 >> macs.monitored_ts[i]) & macs.rx_allocation))
426 macs.rx_monitored |= (UWORD8) (MASK_SLOT0 >> macs.monitored_ts[i]);
427
428 // Clear the USF vote flag
429 macs.usf_vote_enable = 0;
430
431 //if the USF value is GOOD all remaining timelots that needed to be monitored
432 //have to be considered as having GOOD USFs
433 while ((macs.monitored_ts[i] != INVALID) && (i <= 3))
434 {
435 // Update good USFs bitmap
436 macs.usf_good |= (UWORD8) (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY));
437 i++;
438 }
439 macs.next_usf_mon_block[0] = l1s.next_time.block_id + USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity];
440 break;
441 }
442 else
443 {
444 // This timeslot is valid and good
445 macs.usf_good |= (UWORD8) (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY));
446 macs.next_usf_mon_block[macs.monitored_ts[i] - macs.first_monitored_ts] = l1s.next_time.block_id + USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity];
447 }
448 }
449 else //USF is BAD or INVALID
450 {
451 //The TDMA before USF status was not known so USF was supposed to be GOOD but
452 // now it turns out to be BAD or INVALID so block is deallocated.
453 if (macs.tx_data & (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY)))
454 {
455 UWORD8 j;
456
457 // rlc_blocks_sent decremented
458 macs.rlc_blocks_sent --;
459
460 tn = macs.monitored_ts[i];
461
462 #if FF_L1_IT_DSP_USF
463 //For all monitored ts (beginning with last one), if the timeslot is a data block then
464 //data block is shifted to next monitored ts.
465 j=3;
466 while (macs.monitored_ts[j] != tn)
467 {
468 if ((macs.monitored_ts[j] != INVALID) &&
469 (macs.tx_data & (MASK_SLOT0 >> (macs.monitored_ts[j] + RXTX_DELAY))))
470 {
471 macs.ul_buffer_index[macs.monitored_ts[j] + RXTX_DELAY] = macs.ul_buffer_index[macs.monitored_ts[j-1] + RXTX_DELAY];
472 #if L1_EGPRS
473 macs.tx_modulation &= ~(MASK_SLOT0 >> (macs.monitored_ts[j] + RXTX_DELAY));
474 macs.tx_modulation |= ((macs.tx_modulation &
475 (MASK_SLOT0 >> (macs.monitored_ts[j-1] + RXTX_DELAY)))
476 >> (macs.monitored_ts[j]-macs.monitored_ts[j-1]));
477 #endif // L1_EGPRS
478 }
479 j--;
480 }
481
482 // Cancel burst
483 macs.ul_buffer_index[tn + RXTX_DELAY] = INVALID;
484 #if L1_EGPRS
485 macs.tx_modulation &= ~(MASK_SLOT0 >> (tn + RXTX_DELAY));
486 #endif // L1_EGPRS
487 #endif // FF_L1_IT_DSP_USF
488 }//if (macs.tx_data & (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY)))
489 if (SET_PTR->mac_mode == EXT_DYN_ALLOC)
490 {
491 //USF for current timeslot is BAD so it has to be monitored for next USF
492 //period
493 if ((macs.monitored_ts[i] <= macs.lowest_poll_ts) ||
494 ((MASK_SLOT0 >> macs.monitored_ts[i]) & macs.rx_allocation))
495 macs.rx_monitored |= (UWORD8) (MASK_SLOT0 >> macs.monitored_ts[i]);
496 }
497 }
498 }//if(macs.usf_vote_enable & (MASK_SLOT0 >> macs.monitored_ts[i]))
499 i++;
500 }//while ((macs.monitored_ts[i] != INVALID) && (i <= 3))
501
502 if (SET_PTR->mac_mode == EXT_DYN_ALLOC)
503 {
504 // Downlink monitoring is updated depending on USF status
505 macs.rx_allocation |= macs.rx_monitored;
506 }
507
508 // Uplink resources de-allocated by the DSP are de-allocated by MAC-S
509 macs.tx_allocation &= (UWORD8) (macs.usf_good | ~macs.tx_data);
510 macs.tx_data &= (UWORD8) (macs.usf_good | ~macs.tx_data);
511 #endif //#if !L1_EDA
512
513 // Measurement gap processing
514 l1ps_macs_meas();
515
516 } // End if FN13 = 4 OR 8
517 } // End if dynamic allocation mode
518 } // End if uplink TBF
519
520
521 #if FF_L1_IT_DSP_USF
522 if (l1ps_macs_com.usf_status != USF_IT_DSP)
523 {
524 #endif
525
526 /************************************************************/
527 /***** RESSOURCE ALLOCATION FOR THE NEXT BLOCK PERIOD *****/
528 /************************************************************/
529
530 // If the next frame is the first of a block period
531 // FN 13
532 // 0 1 2 3 4 5 6 7 8 9 10 11 12
533 // ----------------------------------------------------------
534 // || B0 || B1 || B2 || I ||
535 // || X | | | || X | | | || X | | | || ||
536 // ----------------------------------------------------------
537
538 if ( (l1s.next_time.fn_mod13 == 4)
539 || (l1s.next_time.fn_mod13 == 8)
540 || (l1s.next_time.fn_mod13 == 0))
541 {
542 UWORD8 tx = 0; // MS class Tx parameter checked
543 UWORD8 rx = 0; // MS class Rx parameter checked
544 UWORD8 tx_no; // Number of allocated uplink timeslots
545 UWORD8 highest_ul_ts; // Highest numbered allocated uplink resource
546 UWORD8 lowest_ul_ts; // Lowest numbered allocated uplink resource
547 UWORD8 highest_dl_ts; // Highest numbered allocated uplink resource
548 UWORD8 lowest_dl_ts; // Lowest numbered allocated uplink resource
549 UWORD8 tra_before_frame; // Number of free Tx slots at the end of the
550 // previous frame
551
552
553 /***********************************************************/
554 /* New allocated ressources */
555 /***********************************************************/
556
557 /*---------------------------------------------------------*/
558 /* New assignment or synchronization change */
559 /*---------------------------------------------------------*/
560
561 if ( (l1ps_macs_com.new_set != FALSE)
562 || (l1a_l1s_com.dl_tn != macs.old_synchro_ts))
563 {
564 UWORD8 tn;
565 UWORD8 fn_mod13;
566 UWORD32 fn_div13;
567
568 /* Fixed allocation mode initialization */
569 /*--------------------------------------*/
570
571 if (SET_PTR->mac_mode == FIX_ALLOC_NO_HALF)
572 {
573 if (((SET_PTR->assignment_command == UL_TBF) || (SET_PTR->assignment_command == BOTH_TBF)) &&
574 (l1ps_macs_com.new_set))
575 {
576 // Starting time block ID processing
577 fn_div13 = (UWORD32) (SET_PTR->tbf_sti.absolute_fn / 13); // FN / 13
578 fn_mod13 = (UWORD8) (SET_PTR->tbf_sti.absolute_fn - (fn_div13 * 13)); // FN mod 13
579 macs.sti_block_id = (UWORD32) ( (3 * (UWORD32) fn_div13) // Block ID
580 + (fn_mod13 / 4));
581
582 // Starting time not aligned on a block period
583 if ((fn_mod13 != 0) && (fn_mod13 != 4) && (fn_mod13 != 8) && (fn_mod13 != 12))
584 macs.sti_block_id ++;
585
586 // Reset the fixed allocation bitmap exhaustion flag only in case of a new assignment
587 macs.fix_alloc_exhaust = FALSE;
588 }
589
590 } // End of fixed mode initialization
591 else
592
593 #if L1_EDA
594 /* Extended Dynamic/Dynamic allocation mode initialization */
595 /*------------------------------------------*/
596
597 if ((SET_PTR->mac_mode == DYN_ALLOC) || (SET_PTR->mac_mode == EXT_DYN_ALLOC))
598 #else
599 /* Dynamic allocation mode initialization */
600 /*------------------------------------------*/
601
602 if (SET_PTR->mac_mode == DYN_ALLOC)
603 #endif
604 {
605 if ((SET_PTR->assignment_command == UL_TBF) || (SET_PTR->assignment_command == BOTH_TBF) ||
606 (l1a_l1s_com.dl_tn != macs.old_synchro_ts))
607 {
608 // USF value aren't kept
609 macs.usf_good = 0;
610 macs.usf_vote_enable = 0; // No USF vote
611 macs.rx_blk_period = NO_DL_BLK;
612
613 if (l1ps_macs_com.new_set)
614 // USF monitoring block set to current block to immediately enable
615 // the USF monitoring in case of new UL TBF
616 macs.next_usf_mon_block[0] = macs.next_usf_mon_block[1] = l1s.next_time.block_id;
617
618 // First and last allocated Tx number updating
619 macs.first_monitored_ts = INVALID;
620 macs.last_monitored_ts = INVALID;
621
622 tn = 0;
623 // Search of the lowest timeslot allocated in uplink
624 while ( !(SET_PTR->ul_tbf_alloc->timeslot_alloc & (MASK_SLOT0 >> tn))
625 && (tn < TS_NUMBER))
626 tn ++;
627
628 if (tn != TS_NUMBER)
629 {
630 macs.first_monitored_ts = tn - l1a_l1s_com.dl_tn;
631 tn = MAX_TS_NB;
632
633 // Search of the highest timeslot allocated in uplink
634 while (!(SET_PTR->ul_tbf_alloc->timeslot_alloc & (MASK_SLOT0 >> tn)))
635 tn --;
636 macs.last_monitored_ts = tn - l1a_l1s_com.dl_tn;
637 #if L1_EDA
638 //Extended Dynamic or Dynamic Allocation has been set
639 {
640 UWORD8 i=0;
641 macs.rx_monitored = 0;
642 //Search among the timeslots allocated in uplink, the timeslots that are really
643 //allocated (macs.first_monitored_ts and macs.last_monitored_ts are for sure
644 //allocated but the allocation can have holes inbetween)
645 for (i = 0; i < 4; i++)
646 {
647 macs.monitored_ts[i] = INVALID;
648 }
649 i = 0;
650 for (tn = macs.first_monitored_ts; tn <= macs.last_monitored_ts; tn++)
651 {
652 //Find the ts that are allocated and need therefore to be monitored
653 if (((SET_PTR->ul_tbf_alloc->timeslot_alloc & (MASK_SLOT0 >> (tn + l1a_l1s_com.dl_tn))) && (SET_PTR->mac_mode == EXT_DYN_ALLOC))
654 || (SET_PTR->mac_mode == DYN_ALLOC))
655 {
656 macs.monitored_ts[i]= tn;
657 i++;
658 }
659 }
660 }
661 #endif //#if L1_EDA
662 }
663 }
664 #if L1_EDA
665 if((SET_PTR->mac_mode == EXT_DYN_ALLOC))
666 l1ps_macs_com.fb_sb_task_detect = TRUE;
667 else
668 l1ps_macs_com.fb_sb_task_detect = FALSE;
669 #endif
670 } // End of dynamic mode initialization
671
672 /* Reset of new_set */
673 /*------------------*/
674
675 l1ps_macs_com.new_set = FALSE;
676
677 } // End of new allocation
678
679 /*---------------------------------------------------------*/
680 /* Resource initialization */
681 /*---------------------------------------------------------*/
682
683 macs.pwr_allocation = 0; // Power measurements
684 macs.rx_allocation = 0; // Rx allocation
685 macs.tx_allocation = 0; // Tx allocation
686 macs.tx_data = 0; // Tx data allocation
687 macs.tx_prach_allocation = 0; // Tx PRACH allocation
688 #if FF_L1_IT_DSP_USF
689 macs.dsp_usf_interrupt = 0; // DSP interrupt for USF decoding needed
690 #endif
691
692 /***********************************************************/
693 /* Downlink TBF processing */
694 /***********************************************************/
695
696 if ((SET_PTR->allocated_tbf == DL_TBF) || (SET_PTR->allocated_tbf == BOTH_TBF))
697 {
698 /* Downlink resources are allocated */
699 macs.rx_allocation = (UWORD8) ( SET_PTR->dl_tbf_alloc.timeslot_alloc
700 << l1a_l1s_com.dl_tn);
701 } /* End if downlink TBF processing */
702
703 /***********************************************************/
704 /* Uplink TBF processing */
705 /***********************************************************/
706
707 if ((SET_PTR->allocated_tbf == UL_TBF) || (SET_PTR->allocated_tbf == BOTH_TBF))
708 {
709
710 /*---------------------------------------------------------*/
711 /* Dynamic allocation mode */
712 /*---------------------------------------------------------*/
713
714 #if L1_EDA
715 if ((SET_PTR->mac_mode == DYN_ALLOC) || (SET_PTR->mac_mode == EXT_DYN_ALLOC))
716 #else
717 if (SET_PTR->mac_mode == DYN_ALLOC)
718 #endif
719 {
720 UWORD8 i;
721 UWORD8 tn;
722 API usf_updated;
723
724 #if !L1_EDA
725 /* Downlink resource monitoring */
726 /*------------------------------*/
727
728 macs.rx_allocation |= (UWORD8) ( SET_PTR->ul_tbf_alloc->timeslot_alloc
729 << l1a_l1s_com.dl_tn);
730
731 /* USF values reading */
732 /*--------------------*/
733
734 // An uplink timeslot is allocated by MAC-S if it's allocated by the network and
735 // - USF is updated and good
736 // OR - USF isn't updated
737
738 // Reading of the d_usf_updated_gprs value
739 usf_updated = NDB_PTR->d_usf_updated_gprs;
740
741 // For each timeslot that can be allocated in uplink...
742 for (tn = macs.first_monitored_ts; tn <= macs.last_monitored_ts; tn ++)
743 {
744 UWORD8 tn_usf;
745 WORD32 delta;
746
747 // Remaining blocks before a new USF reading
748 delta = (WORD8) (macs.next_usf_mon_block[tn - macs.first_monitored_ts] - l1s.next_time.block_id);
749
750 // MAX_FN modulo
751 if (delta <= 0) delta += MAX_BLOCK_ID;
752
753 if (delta >= USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity])
754 {
755 // USF no more usable
756 // Clear USF in good USFs bitmap
757 macs.usf_good &= (UWORD8) ~(MASK_SLOT0 >> (tn + 3));
758
759 // Clear USF vote
760 macs.usf_vote_enable &= (UWORD8) ~(MASK_SLOT0 >> tn);
761
762 // If downlink blocks were entirely received during the last block period
763 if (macs.rx_blk_period == l1s.next_time.block_id)
764 {
765 // Read USF
766 tn_usf = (UWORD8) ((usf_updated >> ((MAX_TS_NB - tn) << 1)) & MASK_2SLOTS);
767
768 if (tn_usf == USF_GOOD)
769 {
770 // Update good USFs bitmap
771 macs.usf_good |= (UWORD8) (MASK_SLOT0 >> (tn + 3));
772 macs.next_usf_mon_block[tn - macs.first_monitored_ts] = l1s.next_time.block_id + USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity];
773 }
774 else
775 if ((tn_usf == USF_INVALID) && (l1s.next_time.fn_mod13 != 0))
776 {
777 // Unknown USF:
778 // - TPU is programmed to tranmit a block on timeslot tn
779 // - DSP will set the TX PWR to 0 for this timeslot is USF is bad
780 // (USF vote mechanism)
781
782 macs.tx_allocation |= (MASK_SLOT0 >> (tn + 3));
783 macs.usf_vote_enable |= (MASK_SLOT0 >> tn);
784 }
785 } // End if "downlink block entirely received"
786 } // End if "USF no more usable"
787 } // End for
788
789 #else //#if !L1_EDA
790 {
791 UWORD8 tn_usf;
792 WORD32 delta;
793 UWORD8 i=0;
794
795 if (SET_PTR->mac_mode == DYN_ALLOC)
796 {
797 /* Downlink resource monitoring */
798 /*------------------------------*/
799
800 macs.rx_allocation |= (UWORD8) ( SET_PTR->ul_tbf_alloc->timeslot_alloc
801 << l1a_l1s_com.dl_tn);
802
803 macs.last_rx_monitored = macs.rx_allocation;
804 }
805 else
806 {
807 // Remaining blocks before a new USF reading
808 delta = (WORD8) (macs.next_usf_mon_block[0] - l1s.next_time.block_id);
809
810 // MAX_FN modulo
811 if (delta <= 0) delta += MAX_BLOCK_ID;
812
813 //Save last rx_monitored timeslots
814 macs.last_rx_monitored = macs.rx_monitored;
815
816 //for all timeslots to monitor (timeslots allocated in UL)
817 for (tn = macs.first_monitored_ts; tn <= macs.last_monitored_ts; tn++)
818 {
819 //All possible timeslots to monitor have to be monitored
820 // (USF validity period exhausted)
821 if (macs.monitored_ts[i] != INVALID)
822 macs.rx_monitored |= (MASK_SLOT0 >> macs.monitored_ts[i]);
823 i++;
824 }
825
826 //USF validity period is exhausted
827 if (delta >= USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity])
828 {
829 //USF need to be evaluated for next block period
830 macs.usf_good = 0;
831 }
832 else
833 {
834 //Set monitored ts again if poll occured on one ts during a block granularity period = 4
835 //note: macs.usf_good is always different from 0
836 i=0;
837 while (!(macs.usf_good & (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY))))
838 i++;
839 macs.rx_monitored &= (UWORD8) ~(MASK_ALL_SLOTS >> macs.monitored_ts[i+1]);
840 }
841 }
842
843 // Reading of the d_usf_updated_gprs value
844 usf_updated = NDB_PTR->d_usf_updated_gprs;
845
846 i=0;
847 //for all possible timeslots to monitor
848 while ((macs.monitored_ts[i] != INVALID) && (i <= 3))
849 {
850 if (SET_PTR->mac_mode == DYN_ALLOC)
851 {
852 // Remaining blocks before a new USF reading
853 delta = (WORD8) (macs.next_usf_mon_block[macs.monitored_ts[i] - macs.first_monitored_ts] - l1s.next_time.block_id);
854
855 // MAX_FN modulo
856 if (delta <= 0) delta += MAX_BLOCK_ID;
857 }
858
859 //USF validity period is exhausted
860 if (delta >= USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity])
861 {
862 if (SET_PTR->mac_mode == DYN_ALLOC)
863 {
864 // USF no more usable
865 // Clear USF in good USFs bitmap
866 macs.usf_good &= (UWORD8) ~(MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY));
867
868 // Clear USF vote
869 macs.usf_vote_enable &= (UWORD8) ~(MASK_SLOT0 >> macs.monitored_ts[i]);
870 }
871
872 if ((macs.rx_blk_period == l1s.next_time.block_id) && (macs.last_rx_monitored & (MASK_SLOT0 >> macs.monitored_ts[i])))
873 {
874
875 #if L1_EGPRS
876 // EGPRS switched radio loopback sub mode on: dynamic allocation
877 // but USF are always deemed to be good
878 if (l1ps_macs_com.loop_param.sub_mode == TRUE)
879 tn_usf = USF_GOOD;
880 else
881 #endif
882 // Read USF
883 tn_usf = (UWORD8) ((usf_updated >> ((MAX_TS_NB - macs.monitored_ts[i]) << 1)) & MASK_2SLOTS);
884
885 if (tn_usf == USF_GOOD)
886 {
887 if (SET_PTR->mac_mode == EXT_DYN_ALLOC)
888 {
889 //Deallocate monitored ts
890 macs.rx_monitored &= (UWORD8) ~(MASK_ALL_SLOTS >> macs.monitored_ts[i+1]);
891
892 //As USF is good for current monitored ts, all subsequent monitored ts have
893 //to be deallocated and the associated USF set to USF_GOOD
894 while ((macs.monitored_ts[i] != INVALID) && (i <= 3))
895 {
896 //Update good USFs bitmap
897 macs.usf_good |= (UWORD8) (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY));
898 i++;
899 }
900 macs.next_usf_mon_block[0] = l1s.next_time.block_id + USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity];
901 break;
902 }
903 else
904 {
905 // Update good USFs bitmap
906 macs.usf_good |= (UWORD8) (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY));
907 macs.next_usf_mon_block[macs.monitored_ts[i] - macs.first_monitored_ts] = l1s.next_time.block_id + USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity];
908 }
909 }
910 else
911 if ((tn_usf == USF_INVALID) && (l1s.next_time.fn_mod13 != 0))
912 {
913 if (SET_PTR->mac_mode == EXT_DYN_ALLOC)
914 {
915 //Deallocate monitored ts
916 macs.rx_monitored &= (UWORD8) ~(MASK_ALL_SLOTS >> macs.monitored_ts[i+1]);
917
918 //As USF is invalid (status of USF not yet known) for current monitored ts, the USF is
919 //supposed to be good and therefore Tx is allocated and all subsequent monitored ts
920 //have to be deallocated. Vote mechanism is also enabled for these latter timeslots.
921 while ((macs.monitored_ts[i] != INVALID) && (i <= 3))
922 {
923 macs.tx_allocation |= (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY));
924 macs.usf_vote_enable |= (MASK_SLOT0 >> macs.monitored_ts[i]);
925 i++;
926 }
927 break;
928 }
929 else
930 {
931 // Unknown USF:
932 // - TPU is programmed to tranmit a block on timeslot tn
933 // - DSP will set the TX PWR to 0 for this timeslot is USF is bad
934 // (USF vote mechanism)
935
936 macs.tx_allocation |= (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY));
937 macs.usf_vote_enable |= (MASK_SLOT0 >> macs.monitored_ts[i]);
938 }
939 }
940 }//if ((macs.rx_blk_period == l1s.next_time.block_id) && (macs.last_rx_monitored & (MASK_SLOT0 >> macs.monitored_ts[i])))
941 }
942 i++;
943 }//while ((tn != INVALID) && (i <= 3))
944 }//if (SET_PTR->mac_mode == EXT_DYN_ALLOC)
945
946 /* Downlink resource monitoring */
947 /*------------------------------*/
948 macs.rx_allocation |= macs.rx_monitored;
949 #endif //#if !L1_EDA
950 /* Uplink resources allocation according to USF values */
951 /*-----------------------------------------------------*/
952
953 i = l1a_l1s_com.dl_tn - RXTX_DELAY;
954 if (i < TS_NUMBER)
955 {
956 macs.tx_allocation |= (UWORD8) ( macs.usf_good
957 & (SET_PTR->ul_tbf_alloc->timeslot_alloc << i));
958 }
959 else
960 {
961 macs.tx_allocation |= (UWORD8) ( macs.usf_good
962 & (SET_PTR->ul_tbf_alloc->timeslot_alloc >> (-i)));
963 }
964
965 #if L1_EDA
966 //if FB/SB activity detected in comming idle frame, some TX burst have to be deallocated
967 //to allow opening of FB/SB window (no TX activity should be scheduled in slots 6 and 7)
968 if (l1ps_macs_com.fb_sb_task_enabled && l1ps_macs_com.fb_sb_task_detect)
969 {
970 macs.tx_allocation &= ~(MASK_SLOT0 >> 6);
971 }
972 #endif
973
974 #if FF_L1_IT_DSP_USF
975 // UL or BOTH TBF with dynamic allocation in use. DSP has to generate
976 // an interrupt for USF validity for the block to be received if it
977 // is either RBN (radio block number) % 3 = 0 or 1.
978
979 if ( (l1s.next_time.fn_mod13 == 0)
980 || (l1s.next_time.fn_mod13 == 4))
981
982 macs.dsp_usf_interrupt = 1;
983 #endif
984
985 } /* end if dynamic allocation mode */
986
987 /*---------------------------------------------------------*/
988 /* Fixed allocation mode */
989 /*---------------------------------------------------------*/
990
991 if (SET_PTR->mac_mode == FIX_ALLOC_NO_HALF)
992 {
993 UWORD8 i;
994 UWORD32 blk_id = l1s.next_time.block_id;
995
996 /* Allocation bitmap isn't exhausted */
997 /*-----------------------------------*/
998
999 if(macs.fix_alloc_exhaust == FALSE)
1000 {
1001
1002 // Allocation exhaustion detection
1003 //---------------------------------
1004
1005 //
1006 // 0 current_fn End of allocation STI FN_MAX
1007 // |-----|---------|--------------------------------------|----||
1008 // |.....|.........| |....||
1009 // |-----|---------|--------------------------------------|----||
1010 //
1011 // In this case, the Starting time is elapsed but current_fn < STI
1012 // ---> We must have (current block_ID - STI_block_ID) > 0
1013 //
1014 if (blk_id < macs.sti_block_id)
1015 {
1016 blk_id += MAX_BLOCK_ID; // MAX_BLOCK_ID is the block ID obtained when fn = FN_MAX
1017
1018 } // End of FN MAX modulo management
1019
1020 #if TESTMODE
1021 // Never let exhaust the UL allocation in test mode packet transfer operation
1022 if (l1_config.TestMode)
1023 blk_id = macs.sti_block_id;
1024 #endif
1025
1026 /* Allocation bitmap isn't exhausted */
1027 if (blk_id < (macs.sti_block_id + SET_PTR->ul_tbf_alloc->fixed_alloc.bitmap_length))
1028 {
1029
1030 // Uplink allocation
1031 //------------------
1032
1033 // Resources are allocated according to the allocation bitmap or ts_override
1034 macs.tx_allocation = (UWORD8)
1035 ( SET_PTR->ul_tbf_alloc->timeslot_alloc
1036 & ( SET_PTR->ul_tbf_alloc->fixed_alloc.bitmap[blk_id - macs.sti_block_id]
1037 | SET_PTR->ts_override));
1038 // Delay
1039 i = l1a_l1s_com.dl_tn - RXTX_DELAY;
1040 if (i > MAX_TS_NB)
1041 macs.tx_allocation >>= (-i);
1042 else
1043 macs.tx_allocation <<= i;
1044
1045 // Monitoring
1046 //-----------
1047
1048 if ((l1s.next_time.fn_mod13 == 0) || (macs.rx_blk_period != l1s.next_time.block_id))
1049 {
1050 // Last frame was an idle frame or was used for another task --> considered as a free frame
1051 tra_before_frame = 8;
1052 }
1053 else
1054 {
1055 tra_before_frame = macs.tra_gap; // Tra gap of last TDMA frame is saved
1056 }
1057
1058 // DOWNLINK CONTROL TIMESLOT ALLOCATION
1059
1060 if ( SET_PTR->ul_tbf_alloc->timeslot_alloc
1061 & (MASK_SLOT0 >> SET_PTR->ul_tbf_alloc->fixed_alloc.ctrl_timeslot))
1062 {
1063 // Tra and Ttb met --> allocates the downlink control timeslot
1064 macs.rx_allocation |= (UWORD8)
1065 (MASK_SLOT0 >> ( SET_PTR->ul_tbf_alloc->fixed_alloc.ctrl_timeslot
1066 - l1a_l1s_com.dl_tn));
1067 }
1068
1069 // UPLINK PDCH MONITORING
1070 else
1071 {
1072 // The control timeslot has been released
1073
1074 // Allocates uplink TBF timeslots for monitoring
1075 macs.rx_allocation |= (UWORD8) ( SET_PTR->ul_tbf_alloc->timeslot_alloc
1076 << l1a_l1s_com.dl_tn);
1077 }
1078
1079 // If Ttb or Tra not respected, the problem comes from uplink TBF
1080 // monitored timeslots
1081 // If Ttb not respected, downlink resources are removed
1082 for(i = 0; i <= MS_CLASS[SET_PTR->multislot_class].ttb; i++)
1083 macs.rx_allocation &= (~((UWORD8)(macs.tx_allocation << i)));
1084
1085 // Tra respect according to the current allocation
1086 for(i = 0; i <= MS_CLASS[SET_PTR->multislot_class].tra; i++)
1087 macs.rx_allocation &= (~((UWORD8)(macs.tx_allocation << (8-i))));
1088
1089 // Tra respect according to the last allocation
1090 if (tra_before_frame < MS_CLASS[SET_PTR->multislot_class].tra)
1091 {
1092 macs.rx_allocation &= MASK_ALL_SLOTS >> (MS_CLASS[SET_PTR->multislot_class].tra - tra_before_frame);
1093 }
1094
1095 #if MACS_STATUS
1096 if (macs.rx_allocation == 0)
1097 {
1098 l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb] = NO_RX_MONITORED;
1099 l1ps_macs_com.macs_status.nb ++;
1100 }
1101 #endif
1102
1103 // Last block of the allocation bitmap... next block will use new settings
1104 // for timeslot monitoring
1105 if ((blk_id + 1) == (macs.sti_block_id + SET_PTR->ul_tbf_alloc->fixed_alloc.bitmap_length))
1106 {
1107 macs.fix_alloc_exhaust = TRUE;
1108 // Informs L1S
1109 l1ps_macs_com.fix_alloc_exhaust_flag = TRUE;
1110 }
1111
1112
1113 } // End if "allocation bitmap isn't exhausted"
1114 else
1115
1116 // Allocation bitmap has exhausted
1117 {
1118 macs.fix_alloc_exhaust = TRUE;
1119 // Informs L1S
1120 l1ps_macs_com.fix_alloc_exhaust_flag = TRUE;
1121
1122 // Allocates uplink TBF timeslots for monitoring
1123 macs.rx_allocation |= (UWORD8) ( SET_PTR->ul_tbf_alloc->timeslot_alloc
1124 << l1a_l1s_com.dl_tn);
1125
1126 }
1127
1128 } // End if "allocation bitmap not exhausted"
1129
1130 /* Allocation bitmap is exhausted */
1131 /*--------------------------------*/
1132 else
1133 {
1134 // Allocates uplink TBF timeslots for monitoring
1135 macs.rx_allocation |= (UWORD8) ( SET_PTR->ul_tbf_alloc->timeslot_alloc
1136 << l1a_l1s_com.dl_tn);
1137
1138 } // End if fixed allocation exhausted
1139
1140 } // End of fixed allocation processing
1141
1142 } // End of uplink TBF processing
1143
1144 /***********************************************************/
1145 /* Allocation parameters checking and updating */
1146 /***********************************************************/
1147 {
1148 UWORD8 ts;
1149 BOOL rx_ts;
1150 BOOL tx_ts;
1151
1152 #if MACS_STATUS
1153 UWORD8 time = INVALID; /* Timeslot counter */
1154 #endif
1155
1156 tx_no = 0;
1157 highest_ul_ts = INVALID;
1158 lowest_ul_ts = INVALID;
1159 highest_dl_ts = INVALID;
1160 lowest_dl_ts = INVALID;
1161
1162 /*---------------------------------------------------------*/
1163 /* Trb, Ttb parameters verification and Rx, Tx number, Sum */
1164 /* and highest_ul_ts parameters processing */
1165 /*---------------------------------------------------------*/
1166
1167 /* We verifies all allocated uplink and downlink timeslots */
1168 for (ts = 0; ts < TS_NUMBER; ts ++)
1169 {
1170 rx_ts = (UWORD8) (macs.rx_allocation & (MASK_SLOT0 >> ts));
1171 tx_ts = (UWORD8) (macs.tx_allocation & (MASK_SLOT0 >> ts));
1172
1173 #if MACS_STATUS
1174
1175 /* If Rx(ts) = 0 and Tx(ts) = 0 */
1176 /*------------------------------*/
1177
1178 if ((!rx_ts) && (!tx_ts))
1179 {
1180 /* time is incremented */
1181 /* If time was invalid, it becomes active */
1182 if (time < TS_NUMBER)
1183 time ++;
1184 if ((time == RX_SLOT)||(time == TX_SLOT))
1185 time = 1;
1186 } /* End if Rx = 0 and Tx = 0 */
1187
1188 /* If Rx(ts) = 1 and Tx(ts) = 1 */
1189 /*------------------------------*/
1190
1191 if ((rx_ts) && (tx_ts))
1192 {
1193 /* error (only type 1 mobiles are supported) */
1194 l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb] = MS_CLASS_TIME_ERROR;
1195 l1ps_macs_com.macs_status.nb ++;
1196 } /* End if Rx = 1 and Tx = 1 */
1197 #endif
1198
1199 /* If Rx(ts) = 1 */
1200 /*---------------*/
1201
1202 if (rx_ts)
1203 {
1204 highest_dl_ts = ts;
1205 #if MACS_STATUS
1206 /* If time is valid (invalid=0xFF) and time<Trb --> error */
1207 if ((time < MS_CLASS[SET_PTR->multislot_class].trb) || (time == TX_SLOT))
1208 {
1209 l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb] = MS_CLASS_TIME_ERROR;
1210 l1ps_macs_com.macs_status.nb ++;
1211 }
1212 time = RX_SLOT;
1213 #endif
1214 /* First Rx updating */
1215 if (lowest_dl_ts == INVALID)
1216 lowest_dl_ts = ts;
1217
1218 } /* End if Rx = 1 */
1219
1220 /* If Tx(ts) = 1 */
1221 /*---------------*/
1222
1223 if (tx_ts)
1224 {
1225 /* Number of Tx is incremented and highest_ul_ts is updated */
1226 tx_no ++;
1227 highest_ul_ts = ts;
1228 #if MACS_STATUS
1229 /* If time is valid (invalid=0xFF) and time<Ttb --> error */
1230 if ( (time < MS_CLASS[SET_PTR->multislot_class].ttb)
1231 || (time == RX_SLOT))
1232 {
1233 l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb] = MS_CLASS_TIME_ERROR;
1234 l1ps_macs_com.macs_status.nb ++;
1235 }
1236 time = TX_SLOT;
1237 #endif
1238 /* First Tx updating */
1239 if (lowest_ul_ts == INVALID)
1240 lowest_ul_ts = ts;
1241
1242 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
1243 if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
1244 trace_info.pdtch_trace.ul_status[ts] |= 0x4;
1245 #endif
1246 } /* End if Tx = 1 */
1247
1248 } /* End for */
1249
1250 /* Rx and Tx MS class parameters are updated */
1251 if (lowest_dl_ts != INVALID)
1252 rx = (UWORD8) (highest_dl_ts - lowest_dl_ts + 1);
1253
1254 if (lowest_ul_ts != INVALID)
1255 tx = (UWORD8) (highest_ul_ts - lowest_ul_ts + 1);
1256
1257 #if MACS_STATUS
1258 // If the Trb parameter isn't respected at the end of
1259 // the TDMA frame --> MS Class isn't suported
1260 // Note: we considered that the first slot of the next TDMA is always a RX
1261 if (time < MS_CLASS[SET_PTR->multislot_class].trb)
1262 {
1263 l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb] = MS_CLASS_TIME_ERROR;
1264 l1ps_macs_com.macs_status.nb ++;
1265 }
1266
1267 /*---------------------------------------------------------*/
1268 /* Sum, Rx and Tx parameters verification */
1269 /*---------------------------------------------------------*/
1270
1271 if ( ((rx + tx) > MS_CLASS[SET_PTR->multislot_class].sum)
1272 ||(rx > MS_CLASS[SET_PTR->multislot_class].rx)
1273 ||(tx > MS_CLASS[SET_PTR->multislot_class].tx))
1274 {
1275 l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb] = MS_CLASS_SUM_ERROR;
1276 l1ps_macs_com.macs_status.nb ++;
1277 }
1278
1279 // If all downlink timeslots are before the first uplink timeslot or after
1280 // the last uplink timeslot, Rx and Tx parameters are met
1281 if ( ( (highest_dl_ts > lowest_ul_ts)
1282 || (lowest_dl_ts > lowest_ul_ts))
1283 && ( (highest_dl_ts < highest_ul_ts)
1284 || (lowest_dl_ts < highest_ul_ts)))
1285 {
1286 l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb] = MS_CLASS_SUM_ERROR;
1287 l1ps_macs_com.macs_status.nb ++;
1288 }
1289
1290 #endif
1291
1292 } /* End of allocation parameters checking and updating */
1293
1294
1295 /***********************************************************/
1296 /* Uplink RLC/MAC blocks management (RLC - DSP interfaces) */
1297 /* PACCH/U placement (Poll response processing) */
1298 /***********************************************************/
1299
1300 {
1301 BOOL poll; // TRUE if the poll response is processed
1302 UWORD8 highest_ul_data; // Highest uplink timeslot assigned for data transfer
1303 UWORD8 tx_allocation_s; // Used for saving of macs.tx_allocation
1304 UWORD8 rx_allocation_s; // Used for saving of macs.rx_allocation
1305 UWORD8 tx_data_s; // Used for saving of macs.tx_data
1306 UWORD8 highest_ul_ts_s; // Used for saving of highest_ul_ts
1307 UWORD8 lowest_ul_ts_s; // Used for saving of lowest_ul_ts
1308 UWORD8 poll_resp_ts; // Timeslot on which the MS must transmit a poll response
1309 UWORD8 ts;
1310 UWORD8 i;
1311 #if L1_EDA
1312 UWORD8 rx_monitored_s; // Used for saving of rx_monitored
1313 #endif
1314
1315 /*---------------------------------------------------------*/
1316 /* Uplink buffer indexes initialization */
1317 /*---------------------------------------------------------*/
1318
1319 macs.ul_buffer_index[0] = macs.ul_buffer_index[1] = macs.ul_buffer_index[2] =
1320 macs.ul_buffer_index[3] = macs.ul_buffer_index[4] = macs.ul_buffer_index[5] =
1321 macs.ul_buffer_index[6] = macs.ul_buffer_index[7] = INVALID;
1322
1323 // Reset all uplink blocks CS-TYPE in order to disable the validity of blocks not sent
1324 for(i=0; i<4; i++)
1325 {
1326 NDB_PTR->a_du_gprs[i][0] = CS_NONE_TYPE;
1327 NDB_PTR->a_pu_gprs[i][0] = CS_NONE_TYPE;
1328 }
1329
1330 /*---------------------------------------------------------*/
1331 /* Uplink RLC/MAC blocks request to RLC (RLC_UPLINK) */
1332 /*---------------------------------------------------------*/
1333
1334 /* All allocated uplink resources are used for data */
1335 macs.tx_data = macs.tx_allocation;
1336 highest_ul_data = highest_ul_ts;
1337
1338 /* RLC UPLINK CALL */
1339 /*-----------------*/
1340
1341 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
1342 if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_UL_NO_TA)
1343 if ((SET_PTR->packet_ta.ta == 255) && (macs.tx_allocation != 0))
1344 Trace_uplink_no_TA();
1345 #endif
1346
1347 #if TESTMODE
1348 if (l1_config.TestMode)
1349 {
1350 l1tm_rlc_uplink (tx_no, (API*) NDB_PTR->a_du_gprs);
1351 }
1352 else
1353 #endif
1354 {
1355 rlc_uplink(SET_PTR->assignment_id, // Assignment ID
1356 tx_no, // Number of timeslot that can be used
1357 // for uplink data block transfer
1358 l1s.next_time.fn, // Next frame number
1359 SET_PTR->packet_ta.ta, // Timing advance value
1360 (API*) NDB_PTR->a_pu_gprs, // Pointer on poll response struct
1361 (API*) NDB_PTR->a_du_gprs, // Pointer on uplink block struct
1362 macs.fix_alloc_exhaust // Set to 1 if fixed allocation exhausted
1363 );
1364 }
1365
1366 #if FF_TBF
1367 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
1368 if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_RLC_PARAM)
1369 {
1370 UWORD32 cs_type = 0;
1371 //Get the cs_type from the UL buffer API header
1372 //The cs_type format: byte0 (LSByte) -indicates the CS type of TS0
1373 //byte1- CS type of TS1
1374 //byt2 - CS type of TS2
1375 //byte3(MSBye) - CS type of TS3
1376 for (i=0;i<tx_no;i++)
1377 {
1378 cs_type |= ((((UWORD8) NDB_PTR->a_du_gprs[i][0]) & CS_GPRS_MASK) << (8*i));
1379
1380 }
1381 Trace_rlc_ul_param(SET_PTR->assignment_id, // Assignment ID
1382 l1s.next_time.fn, // Next frame number
1383 tx_no, // Number of UL timeslot that can be used
1384 SET_PTR->packet_ta.ta, // Timing advance value
1385 macs.fix_alloc_exhaust,
1386 cs_type );
1387 }
1388 #endif
1389 #else
1390 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
1391 if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_RLC_PARAM)
1392 {
1393 Trace_rlc_ul_param(SET_PTR->assignment_id, // Assignment ID
1394 tx_no, // Number of timeslot that can be used
1395 // for uplink data block transfer
1396 l1s.next_time.fn, // Next frame number
1397 SET_PTR->packet_ta.ta, // Timing advance value
1398 (UWORD32) NDB_PTR->a_pu_gprs, // Pointer on poll response struct
1399 (UWORD32) NDB_PTR->a_du_gprs, // Pointer on uplink block struct
1400 macs.fix_alloc_exhaust);
1401 }
1402 #endif
1403 #endif
1404
1405 //i = 0;//OMAPS00090550
1406
1407 /*---------------------------------------------------------*/
1408 /* Poll responses processing */
1409 /*---------------------------------------------------------*/
1410 #if L1_EDA
1411 macs.lowest_poll_ts = INVALID;
1412 #endif
1413
1414 /* While a poll response is requested */
1415 for(i=0;i<=3;i++) //OMAPS00090550
1416 {
1417 if( ((((UWORD8) NDB_PTR->a_pu_gprs[i][0]) & 0xF) == CS1_TYPE_POLL)
1418 || ((((UWORD8) NDB_PTR->a_pu_gprs[i][0]) & 0xF) == CS_PAB8_TYPE)
1419 || ((((UWORD8) NDB_PTR->a_pu_gprs[i][0]) & 0xF) == CS_PAB11_TYPE))
1420 {
1421 poll = TRUE;
1422
1423 // The number of the timeslot on which the poll response is requested is converted to
1424 // become relative to L1 synchronization
1425 poll_resp_ts = (UWORD8) NDB_PTR->a_pu_gprs[i][1]
1426 - l1a_l1s_com.dl_tn
1427 + RXTX_DELAY;
1428
1429 // All timeslots on which a poll is requested are set in last_poll_response.
1430 // last_poll_response will be updated in FN13 = 2, 6 and 10, when the 4th control
1431 // task will be processed for the current block period --> we'll be sure the poll
1432 // responses are entirely transmitted (no BCCH monitoring)
1433 macs.last_poll_response |= (UWORD8) (MASK_SLOT0 >> poll_resp_ts);
1434
1435 // Allocations are saved: it's useful to restore uplink slots that were removed
1436 // for mapping a poll response that is finally not processed
1437 tx_allocation_s = macs.tx_allocation;
1438 rx_allocation_s = macs.rx_allocation;
1439 tx_data_s = macs.tx_data;
1440 lowest_ul_ts_s = lowest_ul_ts;
1441 highest_ul_ts_s = highest_ul_ts;
1442 #if L1_EDA
1443 rx_monitored_s = macs.rx_monitored;
1444 #endif
1445 #if L1_EDA
1446 //In the case of concurrent TBFs in extended dynamic mode, poll response can be canceled
1447 //if response is not done on concurrent timeslots
1448 if (((SET_PTR->allocated_tbf == BOTH_TBF) && (SET_PTR->mac_mode == EXT_DYN_ALLOC)) &&
1449 (!((SET_PTR->dl_tbf_alloc.timeslot_alloc) & (SET_PTR->ul_tbf_alloc->timeslot_alloc)
1450 & (MASK_SLOT0 >> NDB_PTR->a_pu_gprs[i][1]))))
1451 {
1452 // Poll response not done
1453 poll = FALSE;
1454 }
1455 else
1456 #endif
1457 /* If the requested timeslot is allocated for data transfer */
1458 /*----------------------------------------------------------*/
1459
1460 if (macs.tx_data & (MASK_SLOT0 >> poll_resp_ts))
1461 {
1462 /* The slot is removed in tx_data */
1463 /* No allocation modification */
1464 macs.tx_data &= (UWORD8) (~(MASK_SLOT0 >> poll_resp_ts));
1465
1466 #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
1467 RTTL1_FILL_MACS_STATUS(TX_CANCELLED_POLL, poll_resp_ts)
1468 #endif
1469
1470 } /* End if slot allocated for data */
1471
1472 /* If the poll response is requested on an invalid timeslot */
1473 /* i.e: */
1474 /* - Timeslot > 7 or < 0 */
1475 /* - Timeslot that avoid the RX on the first timeslot */
1476 /* according to Ttb */
1477 /*-------------------------------------------------------------*/
1478
1479 else
1480 if ((poll_resp_ts > 7) || (poll_resp_ts <= MS_CLASS[SET_PTR->multislot_class].ttb))
1481 {
1482 // Poll response not done
1483 poll = FALSE;
1484 }
1485
1486 /* If the Tra parameter isn't respected */
1487 /*--------------------------------------*/
1488
1489 #if L1_EDA
1490 //Tra does not always apply with EDA.
1491 else
1492 if (( (MASK_SLOT0 >> poll_resp_ts)
1493 & ( macs.rx_allocation
1494 >> (TS_NUMBER - MS_CLASS[SET_PTR->multislot_class].tra)) && (SET_PTR->mac_mode != EXT_DYN_ALLOC))
1495 || ((poll_resp_ts == 6) && (l1ps_macs_com.fb_sb_task_enabled)))
1496 #else
1497 else
1498 if ( (MASK_SLOT0 >> poll_resp_ts)
1499 & ( macs.rx_allocation
1500 >> (TS_NUMBER - MS_CLASS[SET_PTR->multislot_class].tra)))
1501
1502 #endif
1503 {
1504 // Poll response not done
1505 poll = FALSE;
1506 }
1507
1508 /* Ttb and Tra respected */
1509 /* Poll on a slot not already allocated for uplink data transfer */
1510 /*---------------------------------------------------------------*/
1511
1512 else
1513 {
1514 /* If Ttb parameter isn't respected */
1515 /*-----------------------------------*/
1516
1517 // If one or several downlink timeslots are allocated between:
1518 // - Ttb timeslots before the timeslot to use for poll response
1519 // - AND the last slot of the frame (optimization)
1520 // --> Ttb parameter isn't respected if the poll response is transmitted
1521 // so the RX resources are removed
1522
1523 macs.rx_allocation &= ~((UWORD8) ( macs.rx_allocation
1524 & ( MASK_ALL_SLOTS
1525 >> ( poll_resp_ts
1526 - MS_CLASS[SET_PTR->multislot_class].ttb))));
1527
1528 #if L1_EDA
1529 if (SET_PTR->mac_mode == EXT_DYN_ALLOC)
1530 {
1531 UWORD8 only_monitored_ts;
1532
1533 only_monitored_ts = ~((UWORD8)(SET_PTR->dl_tbf_alloc.timeslot_alloc << l1a_l1s_com.dl_tn)) & macs.rx_monitored;
1534 macs.rx_allocation &= ~(only_monitored_ts & (MASK_ALL_SLOTS >> (poll_resp_ts + 1 - RXTX_DELAY)));
1535 macs.rx_monitored &= macs.rx_allocation;
1536 }
1537 #endif
1538 /* The requested slot is allocated */
1539 macs.tx_allocation |= (UWORD8) (MASK_SLOT0 >> poll_resp_ts);
1540
1541 /* Lowest, highest numbered uplink timeslot and Tx parameter are updated */
1542
1543 if (poll_resp_ts < lowest_ul_ts)
1544 lowest_ul_ts = poll_resp_ts;
1545
1546 if ((poll_resp_ts > highest_ul_ts) || (highest_ul_ts == INVALID))
1547 highest_ul_ts = poll_resp_ts;
1548
1549 tx = (UWORD8) (highest_ul_ts - lowest_ul_ts + 1);
1550
1551 /* Tx and Sum parameters checking */
1552 /*--------------------------------*/
1553
1554 /* While Tx or Sum parameter isn't respected and the poll response hasn't */
1555 /* already been removed */
1556 while ( ( (tx > MS_CLASS[SET_PTR->multislot_class].tx)
1557 || ((rx + tx) > MS_CLASS[SET_PTR->multislot_class].sum))
1558 && (poll == TRUE))
1559 {
1560 /* If no uplink timeslot is used for data */
1561 if (macs.tx_data == 0)
1562 {
1563 /* The poll response isn't processed */
1564 poll = FALSE;
1565 }
1566 else
1567 {
1568 /* Highest uplink PDTCH is removed */
1569 macs.tx_allocation &= (UWORD8) (~(MASK_SLOT0 >> highest_ul_data));
1570 macs.tx_data &= (UWORD8) (~(MASK_SLOT0 >> highest_ul_data));
1571
1572 #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
1573 RTTL1_FILL_MACS_STATUS(TX_CANCELLED_POLL, highest_ul_data)
1574 #endif
1575
1576 /* Lowest, highest numbered uplink timeslot and Tx parameter are updated */
1577
1578 lowest_ul_ts = INVALID;
1579 highest_ul_ts = INVALID;
1580 highest_ul_data = INVALID;
1581
1582 for (ts = 0; ts < TS_NUMBER; ts ++)
1583 {
1584 if (macs.tx_allocation & (MASK_SLOT0 >> ts))
1585 {
1586 if (lowest_ul_ts == INVALID)
1587 lowest_ul_ts = ts;
1588 highest_ul_ts = ts;
1589 if (macs.tx_data & (MASK_SLOT0 >> ts))
1590 highest_ul_data = ts;
1591 }
1592 }
1593
1594 tx = (UWORD8) (highest_ul_ts - lowest_ul_ts + 1);
1595
1596 }
1597 } /* End while Tx or Sum parameter not met */
1598 } /* End of case "poll on a timeslot not already allocated for uplink data transfer"
1599 " Tra and Ttb respected " */
1600
1601 /* If the poll response is done */
1602 /*------------------------------*/
1603 if (poll == TRUE)
1604 {
1605 // Note: Power measurement always found because Tra met
1606
1607 UWORD8 cs_type;
1608 UWORD16 prach_info;
1609 #if L1_EDA
1610 UWORD8 only_monitored_ts;
1611 #endif
1612
1613 cs_type = (UWORD8) ((NDB_PTR->a_pu_gprs[i][0]) & 0xF);
1614 prach_info = (UWORD16) l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[i][2];
1615
1616 if(cs_type == CS_PAB8_TYPE)
1617 {
1618 l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[i][2] = ((API)(l1a_l1s_com.Scell_info.bsic << 2)) |
1619 ((API)(prach_info) << 8);
1620 l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[i][3] = 0;
1621
1622 // macs.tx_prach_allocation is updated
1623 macs.tx_prach_allocation |= (UWORD8) (MASK_SLOT0 >> poll_resp_ts);
1624 }
1625 else
1626 if(cs_type == CS_PAB11_TYPE)
1627 {
1628 l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[i][2] = ((API)(prach_info) << 5);
1629 l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[i][3] = ((API)(l1a_l1s_com.Scell_info.bsic << 10));
1630
1631 // macs.tx_prach_allocation is updated
1632 macs.tx_prach_allocation |= (UWORD8) (MASK_SLOT0 >> poll_resp_ts);
1633 }
1634
1635 #if L1_EDA
1636 only_monitored_ts = ~((UWORD8)(SET_PTR->dl_tbf_alloc.timeslot_alloc << l1a_l1s_com.dl_tn)) & (SET_PTR->ul_tbf_alloc->timeslot_alloc<< l1a_l1s_com.dl_tn);
1637 //lowest_poll_ts variable is used to remove only monitored ts above a ts
1638 //used for a poll.
1639 if (SET_PTR->mac_mode == EXT_DYN_ALLOC)
1640 {
1641 if ((poll_resp_ts - RXTX_DELAY) < macs.lowest_poll_ts)
1642 macs.lowest_poll_ts = (poll_resp_ts - RXTX_DELAY);
1643 }
1644 #endif
1645 #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
1646 RTTL1_FILL_UL_PDTCH(cs_type, tx_allocation_s & (0x80 >> poll_resp_ts), poll_resp_ts + l1a_l1s_com.dl_tn)
1647 #endif
1648
1649 // a_ul_buffer_gprs updating
1650 if(poll_resp_ts < 8)
1651 macs.ul_buffer_index[poll_resp_ts] = i + 8;
1652
1653 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
1654 if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
1655 {
1656 if(poll_resp_ts < 8)
1657 {
1658 trace_info.pdtch_trace.ul_status[poll_resp_ts] |= cs_type << 4;
1659 trace_info.pdtch_trace.ul_status[poll_resp_ts] |= 1;
1660 }
1661 }
1662 #endif
1663 } // End if the poll response is processed
1664
1665 /* If the poll response isn't processed */
1666 /*--------------------------------------*/
1667 else
1668 {
1669 // All allocation parameters that may have been modified to map
1670 // this poll response are restored
1671 macs.tx_allocation = tx_allocation_s;
1672 macs.rx_allocation = rx_allocation_s;
1673 macs.tx_data = tx_data_s;
1674 highest_ul_ts = highest_ul_ts_s;
1675 lowest_ul_ts = lowest_ul_ts_s;
1676
1677 #if FF_TBF
1678 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
1679 if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
1680 trace_info.pdtch_trace.blk_status |= 0x01;
1681 #endif
1682 #else
1683 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
1684 if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
1685 {
1686 trace_info.pdtch_trace.blk_status |= 0x01;
1687 if(poll_resp_ts < 8)
1688 trace_info.pdtch_trace.ul_status[poll_resp_ts] |= 0x08;
1689 //Set the poll reject bit (bit3) of ul_status to 1 to indicate that the
1690 //requested poll response has been rejected by MACS.
1691 }
1692 #endif
1693 #endif
1694
1695 #if MACS_STATUS
1696 l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb]= POLL_ERROR_MS_CLASS;
1697 l1ps_macs_com.macs_status.nb ++;
1698 #endif
1699
1700 #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
1701 RTTL1_FILL_MACS_STATUS(POLL_REJECT, poll_resp_ts)
1702 #endif
1703 } // End if the poll response isn't processed
1704 //The trace for poll response
1705 #if FF_TBF
1706 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
1707 if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_POLL_PARAM)
1708 {
1709 Trace_rlc_poll_param ( poll, //Indicate whether L1 is going to transmit poll resp or not: 0-no, 1-yes
1710 l1s.next_time.fn, //next frm on whih poll resp will be sent
1711 poll_resp_ts, //Timseslot for poll response
1712 macs.tx_allocation,
1713 (UWORD32)macs.tx_data,
1714 macs.rx_allocation,
1715 (UWORD32)macs.last_poll_response,
1716 ((NDB_PTR->a_pu_gprs[i][0]) & CS_GPRS_MASK));
1717
1718 }
1719 #endif
1720 #endif
1721 i ++;
1722
1723 } /* End while a poll response is requested and can be mapped */
1724 } // End of for loop
1725
1726 /*---------------------------------------------------------*/
1727 /* Uplink RLC/MAC data blocks processing */
1728 /*---------------------------------------------------------*/
1729
1730 i = 0;
1731 ts = 0;
1732 macs.rlc_blocks_sent = 0;
1733
1734 // tx_data_s represents here the remaining timeslots that must be associated
1735 // with a RLC/MAC data block
1736 tx_data_s = macs.tx_data;
1737
1738 /* While a timeslot is available to transmit an uplink RLC/MAC data block */
1739 while (tx_data_s != 0)
1740 {
1741 /* If slot is allocated for data transfer */
1742 if (macs.tx_data & (MASK_SLOT0 >> ts))
1743 {
1744 UWORD8 cs_type = (((UWORD8) NDB_PTR->a_du_gprs[i][0]) & 0xF);
1745
1746 /* If no RLC/MAC block is sent by RLC */
1747 /*------------------------------------*/
1748
1749 if (cs_type == CS_NONE_TYPE)
1750 {
1751 // All uplink timeslots used for data and situated after this timeslot
1752 // (inluding this timeslot) are removed
1753 macs.tx_allocation &= (UWORD8) (~( macs.tx_data & (MASK_ALL_SLOTS >> ts)));
1754 macs.tx_data &= (UWORD8) (~(MASK_ALL_SLOTS >> ts));
1755 tx_data_s = 0;
1756
1757 #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
1758 RTTL1_FILL_MACS_STATUS(TX_ALLOWED_NO_BLK, ts)
1759 #if FF_TBF
1760 //Update the ul_status fileds for cond PDTCH trace
1761 //Since this blcok doesn't have any valid CS scheme, cs_type=0 and payload=11
1762 if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
1763 {
1764 //Bits7,6,5,4 (cs_type)of ul_status should all be zeros
1765 trace_info.pdtch_trace.ul_status[ts] &= 0x0f;
1766 //Make the payload as NA
1767 trace_info.pdtch_trace.ul_status[ts] |= 0x03;
1768 }
1769 #endif
1770 #endif
1771 }
1772
1773 /* Else: uplink RLC/MAC data block transfer processing */
1774 /*-----------------------------------------------------*/
1775 else
1776 {
1777 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
1778 if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
1779 {
1780 trace_info.pdtch_trace.ul_status[ts] |= ((UWORD8) cs_type) << 4;
1781 if (cs_type == CS1_TYPE_DATA)
1782 {
1783 //If it is CS1 block, find out whether is it is DATA or CONTROL block.
1784 UWORD8 payload = (((UWORD8) NDB_PTR->a_du_gprs[i][0]) & 0xc0);
1785 if (payload == DATA_BLOCK)
1786 {
1787 //This is a CS1 DATA block. So fillup 10 for the payload field of ul_status
1788 trace_info.pdtch_trace.ul_status[ts] |= 2;
1789 }
1790 else
1791 {
1792 //This is a CS1 CONTROL block. So fillup 01 for the payload field of ul_status
1793 trace_info.pdtch_trace.ul_status[ts] |= 1;
1794 }
1795 }
1796 }
1797 #endif
1798
1799 /* A data block is assigned to timeslot ts */
1800 tx_data_s &= (UWORD8) (~(MASK_SLOT0 >> ts));
1801 /* rlc_blocks_sent value processed */
1802 macs.rlc_blocks_sent ++;
1803 /* Uplink buffer index stored in ul_buffer_index */
1804 macs.ul_buffer_index[ts] = i;
1805
1806 /* Next data block */
1807 i ++;
1808 }
1809
1810 } /* End if slot allocated for data transfer */
1811
1812 /* Next timeslot */
1813 ts ++;
1814 } /* End while */
1815
1816 } /* End of poll responses / uplink blocks processing */
1817
1818 /***********************************************************/
1819 /* Measurement gap allocation */
1820 /***********************************************************/
1821
1822 l1ps_macs_meas();
1823
1824 #if MACS_STATUS
1825 if (macs.pwr_allocation == 0)
1826 {
1827 l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb] = NO_MEAS_MAPPED;
1828 l1ps_macs_com.macs_status.nb ++;
1829 }
1830 #endif
1831
1832 // Initialize the reception block period
1833 macs.rx_blk_period = NO_DL_BLK;
1834
1835 } /* End if next frame is the first of a block period */
1836
1837 /***********************************************************/
1838 /* RLC_DOWNLINK call enabling for uplink PDCH status */
1839 /***********************************************************/
1840
1841 // FN 13
1842 // 0 1 2 3 4 5 6 7 8 9 10 11 12
1843 // ----------------------------------------------------------
1844 // || B0 || B1 || B2 || I ||
1845 // || | | | || X | | | || X | | | || X ||
1846 // ----------------------------------------------------------
1847
1848 if ( (l1s.actual_time.fn_mod13 == 4)
1849 || (l1s.actual_time.fn_mod13 == 8)
1850 || (l1s.actual_time.fn_mod13 == 12))
1851 {
1852 #if (FF_TBF)
1853 l1ps_macs_rlc_uplink_info();
1854 #else
1855 l1ps_macs_com.rlc_downlink_call = TRUE;
1856 #endif
1857
1858 // RTT: trace UL PDTCH blocks
1859 #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
1860 if (SELECTED_BITMAP(RTTL1_ENABLE_UL_PDTCH))
1861 {
1862 UWORD8 i,j = 0;
1863
1864 for(i=2; i < 8; i++)
1865 {
1866 if (macs.tx_data & (0x80 >> i))
1867 {
1868 RTTL1_FILL_UL_PDTCH((((UWORD8) NDB_PTR->a_du_gprs[j][0]) & 0xF), 1, i)
1869 j++;
1870 }
1871 }
1872 }
1873 #endif
1874 }
1875
1876 #if FF_L1_IT_DSP_USF
1877 } // if (l1ps_macs_com.usf_status != USF_IT_DSP)
1878 #endif // FF_L1_IT_DSP_USF
1879
1880
1881 /***********************************************************/
1882 /* MAC-S control result for LAYER 1 */
1883 /***********************************************************/
1884
1885 /* We update allocation structures in Layer 1 - MAC-S interface */
1886 l1ps_macs_com.rx_allocation = macs.rx_allocation;
1887 l1ps_macs_com.tx_nb_allocation = macs.tx_allocation & (~macs.tx_prach_allocation);
1888 l1ps_macs_com.tx_prach_allocation = macs.tx_prach_allocation;
1889 l1ps_macs_com.pwr_allocation = macs.pwr_allocation;
1890
1891
1892 #if FF_L1_IT_DSP_USF
1893 // When dynamic allocation is in use for uplink TBF, notifies L1S about
1894 // USF uncertainty for FN%13=3 and 7
1895 if (l1ps_macs_com.usf_status != USF_IT_DSP)
1896 {
1897 if (macs.usf_vote_enable)
1898 l1ps_macs_com.usf_status = USF_AWAITED;
1899 else
1900 l1ps_macs_com.usf_status = USF_AVAILABLE;
1901 }
1902 #endif // FF_L1_IT_DSP_USF
1903
1904 /***********************************************************/
1905 /* DSP programming */
1906 /***********************************************************/
1907
1908 // Write uplink blocks - timeslots correspondance in a_ul_buffer_gprs
1909 // MAC mode in d_sched_mode_gprs and the USF table in a_usf_gprs (Each frame)
1910
1911 #if FF_L1_IT_DSP_USF
1912 if (l1ps_macs_com.usf_status != USF_AWAITED)
1913 #endif // FF_L1_IT_DSP_USF
1914
1915 l1pddsp_transfer_mslot_ctrl
1916 (l1s.next_time.fn_mod13_mod4, // Burst number (0 to 3)
1917 macs.rx_allocation, // DL Bitmap
1918 macs.tx_allocation, // UL Bitmap
1919 SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_table, // USF table
1920 SET_PTR->mac_mode, // MAC mode
1921 macs.ul_buffer_index, // UL buffer index
1922 SET_PTR->tsc, // Training sequence code
1923 l1a_l1s_com.dedic_set.radio_freq, // Radio Freq. used for I/Q swap.
1924 l1a_l1s_com.dl_tn, // DL Transfer Sync. TN.
1925 #if FF_L1_IT_DSP_USF
1926 macs.dsp_usf_interrupt // USF interrupt activation
1927 #else
1928 macs.usf_vote_enable // USF vote activation
1929 #endif
1930 );
1931
1932
1933 /*****************************************************************/
1934 /* TBF parameters saving and updating */
1935 /* last_rx_allocation, TFI, rlc_blocks_sent and last_poll_error */
1936 /*****************************************************************/
1937
1938 // FN 13
1939 // 0 1 2 3 4 5 6 7 8 9 10 11 12
1940 // ----------------------------------------------------------
1941 // || B0 || B1 || B2 || I ||
1942 // || | | | X || | | | X || | | | X || ||
1943 // ----------------------------------------------------------
1944
1945 if ( (l1s.next_time.fn_mod13 == 3)
1946 || (l1s.next_time.fn_mod13 == 7)
1947 || (l1s.next_time.fn_mod13 == 11))
1948 {
1949 // Downlink blocks to report to RLC
1950 macs.last_rx_alloc = macs.rx_allocation;
1951 macs.rx_blk_period = l1s.next_time.block_id + 1;
1952 if (macs.rx_blk_period > MAX_BLOCK_ID)
1953 macs.rx_blk_period -= (UWORD32) (MAX_BLOCK_ID + 1);
1954
1955 // Synchronization memorization for synchro. change detection
1956 macs.old_synchro_ts = l1a_l1s_com.dl_tn;
1957
1958 macs.tx_allocation = 0;
1959 macs.tx_prach_allocation = 0;
1960 } /* End if FN13 = 2, 6 OR 10 */
1961
1962 } /* END OF L1PS_MACS_CTRL() */
1963
1964 /*-----------------------------------------------------------*/
1965 /* l1ps_macs_read() */
1966 /*-----------------------------------------------------------*/
1967 /* Parameters: global l1ps_macs_com unchanged */
1968 /* global l1s unchanged */
1969 /* global l1a_l1s_com unchanged */
1970 /* global l1ps_dsp_com changed */
1971 /* */
1972 /* Return: */
1973 /* */
1974 /* Description: l1ps_macs_read checks the last received */
1975 /* downlink blocks. It checks if the TFI field */
1976 /* is present and good in the block header and */
1977 /* write in the NDB the number of received */
1978 /* received blocks and on which timeslot was */
1979 /* received each data block and how much block. */
1980 /* Then the RLC layer is called (rlc_downlink) */
1981 /*-----------------------------------------------------------*/
1982 void l1ps_macs_read(UWORD8 pr_table[8])
1983 {
1984 #define NDB_PTR l1ps_dsp_com.pdsp_ndb_ptr
1985
1986 /***********************************************************/
1987 /* Downlink RLC/MAC block management */
1988 /***********************************************************/
1989
1990 // If we are in the first frame after a block period */
1991 // FN 13
1992 // 0 1 2 3 4 5 6 7 8 9 10 11 12
1993 // ----------------------------------------------------------
1994 // || B0 || B1 || B2 || I ||
1995 // || | | | || X | | | || X | | | || X ||
1996 // ----------------------------------------------------------
1997 // X: Received downlink RLC/MAC block management
1998 if ( (l1s.actual_time.fn_mod13 == 4)
1999 ||(l1s.actual_time.fn_mod13 == 8)
2000 ||(l1s.actual_time.fn_mod13 == 12))
2001 {
2002 UWORD8 ts; // Timeslot pointer
2003 BOOL tfi_result; // Set to 1 if the TFI field is present and good
2004 #if FF_TBF
2005 UWORD8 cs_type;
2006 BOOL crc_error = 0;
2007 #endif
2008
2009 /* For each radio block allocated for downlink transfer in the last block period */
2010 for (ts = 0; ts < TS_NUMBER; ts ++)
2011 {
2012 if (macs.last_rx_alloc & (MASK_SLOT0 >> ts))
2013 {
2014 l1ps_macs_header_decoding(macs.rx_no, &tfi_result, &(pr_table[ts]));
2015
2016 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
2017 if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
2018 {
2019 trace_info.pdtch_trace.dl_status[macs.rx_no] |= tfi_result << 4;
2020 #if FF_TBF
2021 crc_error = NDB_PTR->a_dd_gprs[macs.rx_no][0] & (1<<B_CRC_BLOCK_ERROR);
2022 //In the case of GPRS b_cs_type is 4bit info.
2023 cs_type = NDB_PTR->a_dd_gprs[macs.rx_no][0] & CS_GPRS_MASK;
2024 #if L1_EGPRS
2025 }
2026 #endif
2027 //If the blcok received is in CRC error, update the bit0 of dl_status as 1
2028 if (crc_error == (1<<B_CRC_BLOCK_ERROR))
2029 {
2030 trace_info.pdtch_trace.dl_status[macs.rx_no] |= 0x01;
2031 }
2032 else
2033 {
2034 // No CRC error. Good Block
2035 //dl_cs_type used only for BINARY TRACE. We put the following limitation so that
2036 //in the case of EGPRS with MCS we don't enter here.
2037 if ((cs_type > CS1_TYPE_DATA) && (cs_type <= CS4_TYPE))
2038 {
2039 trace_info.pdtch_trace.dl_cs_type |= ((cs_type - 3) & 3) << (macs.rx_no * 2);
2040 }
2041 }
2042 #else
2043 if (l1ps_dsp_com.pdsp_ndb_ptr->a_dd_gprs[macs.rx_no][0] & 0x0100) // CRC error
2044 trace_info.pdtch_trace.dl_status[macs.rx_no] = 1;
2045 else
2046 {
2047 // CS type
2048 UWORD8 cs_type = NDB_PTR->a_dd_gprs[macs.rx_no][0] & 0xf;
2049
2050 if (cs_type != CS1_TYPE_DATA)
2051 trace_info.pdtch_trace.dl_cs_type |= ((cs_type - 3) & 3) << macs.rx_no;
2052 }
2053 #endif
2054 }
2055 #endif
2056
2057 // TFI filtering result stored in the downlink block buffer header
2058 NDB_PTR->a_dd_gprs[macs.rx_no][0] &= (API) (TFI_BIT_MASK);
2059 NDB_PTR->a_dd_gprs[macs.rx_no][0] |= (API) (tfi_result << TFI_BIT_SHIFT);
2060
2061 /*---------------------------------------------------------*/
2062 /* Timeslot and Rx_no values updating */
2063 /*---------------------------------------------------------*/
2064
2065 // Timeslot number (relative to the network) on which the block was received is
2066 // stored in the downlink block buffer header
2067
2068 NDB_PTR->a_dd_gprs[macs.rx_no][1] = ts + l1ps.read_param.dl_tn;
2069
2070 #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
2071 RTTL1_FILL_DL_PDTCH((UWORD8) (NDB_PTR->a_dd_gprs[macs.rx_no][4]), \
2072 tfi_result, \
2073 NDB_PTR->a_dd_gprs[macs.rx_no][0] & 0x0100 >> 8, \
2074 NDB_PTR->a_dd_gprs[macs.rx_no][0] & 0x000f, \
2075 ts + l1ps.read_param.dl_tn)
2076 #endif
2077
2078 macs.rx_no ++;
2079
2080 } /* End if timeslot was allocated in downlink for the last block period */
2081 } /* Next timeslot (FOR statement) */
2082
2083 #if FF_TBF
2084 //The "rlc_downlink_bufferize_param" structure is used to memorize parameters
2085 //over a block period in order to cope with spreading issue.
2086 //
2087 // C|W R |
2088 // |C W R |
2089 // | C W R| TBF 1
2090 // | C W|R <------------
2091 //----------------------
2092 // | C|W R <--------------
2093 // | |C W R
2094 // | | C W R TBF 2
2095 // | | C W R
2096 // ^
2097 // |
2098 // worst case where the rlc_downlink() function can be called
2099 // when spreading occurs
2100
2101 //the case above depicts a new TBF assignment without change of the synchronization:
2102 //as the call to the rlc_downlink() function (that needs among other the assignment id parameter)
2103 //can be delayed due to spreading, the assignment id of TBF 1 should be memorized
2104 //until the call of the rlc_downlink() function that handles the last block of TBF 1
2105
2106 l1ps_macs_com.rlc_downlink_bufferize_param.allocated_tbf = l1ps.read_param.allocated_tbf;
2107 l1ps_macs_com.rlc_downlink_bufferize_param.assignment_id = l1ps.read_param.assignment_id;
2108 #if L1_EGPRS
2109 l1ps_macs_com.rlc_downlink_bufferize_param.tbf_mode = l1ps.read_param.tbf_mode;
2110 #endif
2111
2112 // New buffer to be allocated
2113 macs.dl_buffer_index = INVALID;
2114 // Initialize spreading counter
2115 macs.tdma_delay = 0;
2116
2117 // rlc_uplink_info() invokation in case of block skipped due to resynchro
2118 // See L1_MCU-CHG-17924
2119 if (l1s.task_status[PDTCH].current_status != RE_ENTERED)
2120 l1ps_macs_rlc_uplink_info();
2121 #endif
2122 /***********************************************************/
2123 /* RLC_DOWNLINK call enabling for downlink PDCH status */
2124 /***********************************************************/
2125 l1ps_macs_com.rlc_downlink_call = TRUE;
2126
2127 #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
2128 #if L1_BINARY_TRACE == 0
2129 if (trace_info.current_config->l1_dyn_trace & (1<<L1_DYN_TRACE_DL_PDTCH_CRC))
2130 {
2131 BOOL crc_error=0;
2132 UWORD8 i;
2133
2134 for(i=0;i<macs.rx_no;i++)
2135 crc_error |= ((NDB_PTR->a_dd_gprs[i][0] & 0x0100) >> (1+i));
2136
2137 Trace_Packet_Transfer(crc_error); // Previous RX blocks CRC_ERROR summary
2138 }
2139 #endif
2140 #endif
2141
2142 } /* End if first frame after a block period */
2143
2144 } /* END OF L1PS_MACS_READ */
2145
2146 /*-----------------------------------------------------------*/
2147 /* l1ps_macs_meas() */
2148 /*-----------------------------------------------------------*/
2149 /* Parameters: global l1ps_macs_com unchanged */
2150 /* global l1a_l1s_com unchanged */
2151 /* static macs.rx_allocation unchanged */
2152 /* static macs.tx_allocation unchanged */
2153 /* static macs.pwr_allocation changed */
2154 /* Return: */
2155 /* */
2156 /* Description: This function processes the power measurement*/
2157 /* gap according to the MS class and timeslots */
2158 /* allocated in macs.tx_allocation and */
2159 /* macs.rx_allocation fields. */
2160 /*-----------------------------------------------------------*/
2161 void l1ps_macs_meas()
2162 {
2163 #define SET_PTR l1pa_l1ps_com.transfer.aset
2164
2165 WORD8 ts = 7; // Timeslot pointer
2166 UWORD8 gap = 0; // Gap size counter
2167 UWORD8 meas = 0; // Temporary gap processing
2168 UWORD8 bitmap_rx, bitmap_tx;
2169
2170 macs.pwr_allocation = 0;
2171 bitmap_rx = macs.rx_allocation;
2172 bitmap_tx = macs.tx_allocation;
2173
2174 // Searching of the last allocated timeslot
2175 // Note: Layer 1 always synchronize on a RX event, so the Tra gap will always
2176 // be found after the last allocated timeslot of a frame
2177
2178 while ( (ts >= 0)
2179 && ((bitmap_rx & 0x01) == 0)
2180 && ((bitmap_tx & 0x01) == 0))
2181 {
2182 // Memorization of the timeslot
2183 meas |= (UWORD8) (MASK_SLOT0 >> ts);
2184 // Gap is incremented
2185 gap ++;
2186
2187 bitmap_rx >>= 1;
2188 bitmap_tx >>= 1;
2189 ts --;
2190 }
2191
2192 // Last allocated timeslot: ts
2193 // Power gap size: gap
2194
2195 // Save the "tra gap" at the end of the frame
2196 macs.tra_gap = gap;
2197
2198 // If Tra respected before the first Rx of the frame after
2199 // Here we consider that L1 is ALWAYS synchronized on a RX timeslot
2200 if (gap >= MS_CLASS[SET_PTR->multislot_class].tra)
2201 {
2202 // The gap is allocated
2203 macs.pwr_allocation |= meas;
2204 }
2205 else
2206 // If the first slot of the next frame is free and permit to respect the Tra parameter
2207 // in fixed mode
2208 // Notes:
2209 // - if Tra not respected and the current slot 0 isn't allocated --> the slot 0 of
2210 // the next frame will not be allocated (only possible in Fixed mode)
2211 // - in all cases, only one timeslot need to be removed
2212 if ( (gap + 1 >= MS_CLASS[SET_PTR->multislot_class].tra)
2213 && (!(macs.rx_allocation & MASK_SLOT0)))
2214 {
2215 // The gap is allocated
2216 macs.pwr_allocation |= meas;
2217 }
2218
2219 #if L1_EDA
2220 //if in extended dynamic allocation and if no power measurement is set in Tra gap (Tra not fulfilled)
2221 //then power measurement is set in Tta gap if MS class supports it.
2222 if ((SET_PTR->mac_mode == EXT_DYN_ALLOC) && (!macs.pwr_allocation))
2223 {
2224 UWORD8 i = MAX_TS_NB;
2225
2226 //compute tta
2227 while (!(macs.rx_allocation & (MASK_SLOT0 >> i)))
2228 i--;
2229
2230 i++;
2231 gap = 0;
2232 meas = 0;
2233 while (!(macs.tx_allocation & (MASK_SLOT0 >> i)))
2234 {
2235 gap++;
2236 meas |= (UWORD8) (MASK_SLOT0 >> i);
2237 i++;
2238 }
2239
2240 if (gap <= MS_CLASS[SET_PTR->multislot_class].tta)
2241 macs.pwr_allocation |= meas;
2242 }
2243 #endif //#if L1_EDA
2244 } /* End of l1ps_macs_meas */
2245
2246 /*-----------------------------------------------------------*/
2247 /* l1ps_macs_header_decoding() */
2248 /*-----------------------------------------------------------*/
2249 /* Parameters: */
2250 /* */
2251 /* Return: */
2252 /* */
2253 /* Description: This function process the TFI filtering and */
2254 /* decode the PR value in the MAC header of the */
2255 /* block stored in buffer rx_no. */
2256 /*-----------------------------------------------------------*/
2257 void l1ps_macs_header_decoding(UWORD8 rx_no, UWORD8 *tfi_result, UWORD8 *pr)
2258 {
2259 UWORD8 payload; // Payload type value in the RLC/MAC header
2260 UWORD8 tfi; // TFI value
2261 UWORD16 mac_header[2]; // Downlink block MAC header
2262
2263 *pr = 0;
2264
2265 // DSP Driver
2266 // Downlink block MAC header reading
2267
2268 mac_header[0] = NDB_PTR->a_dd_gprs[rx_no][4];
2269 mac_header[1] = NDB_PTR->a_dd_gprs[rx_no][5];
2270
2271 *tfi_result = TFI_NOT_FILTERED;
2272
2273 #if TFI_FILTERING
2274
2275 /*---------------------------------------------------------*/
2276 /* TFI Filtering */
2277 /*---------------------------------------------------------*/
2278
2279 *tfi_result = TFI_BAD;
2280
2281 /* Payload reading in the block header */
2282 /*-------------------------------------*/
2283
2284 payload = (UWORD8) (((mac_header[0]) >> PAYLOAD_SHIFT) & PAYLOAD_MASK);
2285
2286 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
2287 if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
2288 {
2289 trace_info.pdtch_trace.dl_status[rx_no] |= payload << 6;
2290 // RRBP + S/P trace
2291 trace_info.pdtch_trace.dl_status[rx_no] |= (mac_header[0] & (0x38)) >> 2;
2292 }
2293 #endif
2294
2295 /* If the payload time isn't "RESERVED" */
2296 if (payload != RESERVED)
2297 {
2298 /* Data block case, processed if a downlink TBF is assigned */
2299 /*----------------------------------------------------------*/
2300
2301 if (payload == DATA_BLOCK)
2302 {
2303 *pr = (UWORD8) ((mac_header[0] >> DATA_PR_SHIFT) & PR_MASK);
2304
2305 if ((l1ps.read_param.allocated_tbf == DL_TBF) || (l1ps.read_param.allocated_tbf == BOTH_TBF))
2306 {
2307 // TFI value reading
2308 tfi = (UWORD8) ((mac_header[0] & DATA_TFI_MASK) >> DATA_TFI_SHIFT);
2309
2310 // Downlink TFI control
2311 if (tfi == l1ps.read_param.dl_tfi)
2312 {
2313 *tfi_result = TFI_GOOD;
2314 }
2315 } // End if "downlink TBF enabled"
2316
2317 } /* End of data block case */
2318
2319 /* Control block case */
2320 /*--------------------*/
2321
2322 else
2323 {
2324 /* Optionnal field is no present */
2325 if (payload == CTRL_NO_OPTIONAL)
2326 *tfi_result = TFI_NOT_PRESENT;
2327
2328 /* Optionnal field is present */
2329 if (payload == CTRL_OPTIONAL)
2330 {
2331 *pr = (UWORD8) ((mac_header[1] >> CTRL_PR_SHIFT) & PR_MASK);
2332
2333 /* AC = 1 : TFI is present */
2334 if (mac_header[0] & AC_MASK)
2335 {
2336 // TFI value reading
2337 tfi = (UWORD8) ((mac_header[1] & CTRL_TFI_MASK) >> CTRL_TFI_SHIFT);
2338
2339 /* If direction is downlink TBF (D = 1) and a downlink TBF is in progress */
2340 if ( mac_header[1] & MASK_D)
2341 {
2342 if ( (l1ps.read_param.allocated_tbf == DL_TBF)
2343 || (l1ps.read_param.allocated_tbf == BOTH_TBF))
2344 {
2345 // Downlink TFI value is checked
2346 if (tfi == l1ps.read_param.dl_tfi)
2347 {
2348 *tfi_result = TFI_GOOD;
2349 }
2350 }
2351 } /* End if direction is downlink */
2352
2353 /* If direction is uplink TBF (D = 0) and an uplink TBF is in progress */
2354 else if ( (l1ps.read_param.allocated_tbf == UL_TBF)
2355 || (l1ps.read_param.allocated_tbf == BOTH_TBF))
2356 {
2357 // Uplink TFI value is checked
2358 if (tfi == l1ps.read_param.ul_tfi)
2359 {
2360 *tfi_result = TFI_GOOD;
2361 }
2362
2363 } /* End if direction is uplink */
2364
2365 } /* End if AC = 1 */
2366
2367 /* AC = 0 : TFI is no present */
2368 else
2369 *tfi_result = TFI_NOT_PRESENT;
2370
2371 } // End if control block with optionnal field
2372
2373 } // End of control block case
2374
2375 } // End if PAYLOAD != "RESERVED"
2376
2377 #endif
2378
2379 /*---------------------------------------------------------*/
2380 /* pr_table updating */
2381 /*---------------------------------------------------------*/
2382
2383 if(l1ps.read_param.dl_pwr_ctl.p0 == 255)
2384 *pr = 0; // PR unused in "No power control" mode
2385 else
2386 *pr = PR_CONVERSION[l1ps.read_param.dl_pwr_ctl.bts_pwr_ctl_mode][*pr];
2387
2388 // If TFI isn't good
2389 if (*tfi_result != TFI_GOOD)
2390 {
2391 // Set bit 7 to 1
2392 *pr |= 0x80;
2393 }
2394
2395 }
2396
2397 /*-----------------------------------------------------------*/
2398 /* l1ps_macs_rlc_downlink_call() */
2399 /*-----------------------------------------------------------*/
2400 /* Parameters: */
2401 /* */
2402 /* Return: */
2403 /* */
2404 /* Description: This function is called at the end of L1S */
2405 /* execution if RLC_DOWNLINK must be called. */
2406 /* */
2407 /*-----------------------------------------------------------*/
2408 void l1ps_macs_rlc_downlink_call(void)
2409 {
2410 UWORD8 i;
2411 #if FF_TBF
2412 UWORD32 fn;
2413 BOOL rlc_dl_call = FALSE;
2414 API* rlc_buffer;
2415 API* dummy_rlc_buffer = NULL;
2416
2417 //correct reporting of FN to L3 should be TDMA 4, 8 or 12 of MF13
2418 fn=l1s.actual_time.fn-l1s.actual_time.fn_mod13_mod4;
2419
2420 //when fn is in first block of the MF13 (which value is not a correct value
2421 //to report to upper layer) then fn should be decremented so that fn%13 = 12
2422 if(l1s.actual_time.fn_mod13 <= 3)
2423 fn--;
2424
2425 //to cope with border case
2426 // if (fn < 0) //OMAPS00090550
2427 // fn += MAX_FN - 1; //OMAPS00090550
2428
2429 // Retrieve decoded blocks from API. All payload decoded check.
2430 if (!rlc_downlink_copy_buffer(FALSE))
2431 {
2432 // Flag RLC call
2433 rlc_dl_call = TRUE;
2434
2435 // RLC buffer exhaustion check
2436 if ((macs.dl_buffer_index == INVALID) || (l1a_l1s_com.recovery_flag))
2437 {
2438 if (macs.tdma_delay >= 3)
2439 {
2440 // No block reported ever by DSP
2441 // #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
2442 // l1_trace_egprs(NO_BLOCKS_PASSED_TO_L3);
2443 // #endif
2444
2445 #if (TRACE_TYPE==5)
2446 trace_fct_simu("MACS ERROR: No RLC blocks passed to L3 on current frame", 0);
2447 sprintf(errormsg,"MACS ERROR: No RLC blocks passed to L3 on current frame");
2448 log_sim_error(ERR);
2449 #endif
2450 }
2451 else
2452 {
2453 // No RLC buffer available
2454
2455 #if (TRACE_TYPE==5)
2456 trace_fct_simu("MACS ERROR: No free buffer to copy RLC blocks on current frame", 0);
2457 //sprintf(errormsg,"MACS ERROR: No free buffer to copy RLC blocks on current frame");
2458 //log_sim_error(ERR);
2459 #endif
2460 }
2461
2462 // Dummy buffer to be reported
2463 rlc_buffer = (API*) dummy_rlc_buffer;
2464 }
2465 // RLC buffer has been succesfully allocated
2466 else
2467 {
2468 // RLC buffer to be reported
2469 rlc_buffer = (API*) &(macs.rlc_dbl_buffer[macs.dl_buffer_index].d_rlcmac_rx_no_gprs);
2470
2471 #if (TRACE_TYPE == 1)||(TRACE_TYPE == 4)
2472 #if L1_BINARY_TRACE == 0
2473 if (trace_info.current_config->l1_dyn_trace & (1<<L1_DYN_TRACE_DL_PDTCH_CRC))
2474 {
2475 BOOL crc_error=0;
2476 UWORD8 i;
2477 #if L1_EGPRS
2478 if (l1ps_macs_com.rlc_downlink_bufferize_param.tbf_mode == TBF_MODE_EGPRS)
2479 {
2480 for(i=0;i<macs.rlc_dbl_buffer[macs.dl_buffer_index].d_rlcmac_rx_no_gprs;i++)
2481 crc_error |= ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & (1 << B_CRC_BLOCK_ERROR)) >> (1+i));
2482 }
2483 else
2484 #endif
2485 {
2486 for(i=0;i<macs.rlc_dbl_buffer[macs.dl_buffer_index].d_rlcmac_rx_no_gprs;i++)
2487 crc_error |= ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_gprs[i][0] & (1 << B_CRC_BLOCK_ERROR)) >> (1+i));
2488 }
2489 Trace_Packet_Transfer(crc_error); // Previous RX blocks CRC_ERROR summary
2490 }
2491 #endif
2492 #endif
2493 #if L1_EGPRS
2494 // IR testing specific trace
2495 #if (TRACE_TYPE == 1)||(TRACE_TYPE == 4)
2496 if ((trace_info.current_config->l1_dyn_trace & (1<<L1_DYN_TRACE_IR))
2497 && (l1ps_macs_com.rlc_downlink_bufferize_param.tbf_mode == TBF_MODE_EGPRS))
2498 {
2499 UWORD8 j ;
2500 // Clear ir trace variables
2501 trace_info.ir_trace.crc = 0;
2502 trace_info.ir_trace.mcs = 0;
2503 trace_info.ir_trace.status_ir_tfi = 0;
2504 trace_info.ir_trace.puncturing = 0;
2505
2506 for(j=0;j<MS_CLASS[MAX_CLASS].rx;j++)
2507 {
2508 trace_info.ir_trace.bsn[j] = 0;
2509 trace_info.ir_trace.cv_bep_egprs[j]= 0;
2510 trace_info.ir_trace.mean_bep_egprs[j] = 0;
2511 }
2512
2513 // Retrieve IR info from every PDCH
2514 for(i=0;i<macs.rlc_dbl_buffer[macs.dl_buffer_index].d_rlcmac_rx_no_gprs;i++)
2515 {
2516 UWORD16 crc;
2517 UWORD16 bsn1, bsn2;
2518 UWORD8 mcs;
2519 UWORD8 cps;
2520 UWORD8 k;
2521
2522 // retrieve coding scheme
2523 mcs = (macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & CS_EGPRS_MASK);
2524
2525 j = k = 0 ;
2526
2527 // retrieve BSN
2528 switch (mcs)
2529 {
2530 case CS1_TYPE_POLL:
2531 case CS1_TYPE_DATA:
2532 case CS2_TYPE:
2533 case CS3_TYPE:
2534 case CS4_TYPE:
2535 // GPRS data block
2536 if ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & (1 << B_CRC_BLOCK_ERROR)) || (mcs == CS1_TYPE_POLL))
2537 bsn1 = 0xffff;
2538 else
2539 bsn1 = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 1] >> 1) & 0x7f);
2540 bsn2 = 0;
2541
2542 crc = (macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & ((1 << B_CRC_HEADER_ERROR) + (1 << B_CRC_PAYLOAD1_ERROR) + (1 << B_CRC_BLOCK_ERROR)));
2543 crc = (crc >> B_CRC_HEADER_ERROR);
2544 break;
2545
2546 case MCS1_TYPE:
2547 case MCS2_TYPE:
2548 case MCS3_TYPE:
2549 case MCS4_TYPE:
2550 // rlc mac header type 3
2551 cps = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 1]) >> 9) & 0x0F ;
2552 j = 255 ; // cps is set
2553 case MCS5_TYPE:
2554 case MCS6_TYPE:
2555 // rlc mac header type 2
2556 if (j != 255)
2557 {
2558 cps = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 1]) >> 9) & 0x07 ;
2559 }
2560 do
2561 {
2562 if (cps == CPS_value1_6[k][mcs-MCS1_TYPE])
2563 { // set puncturing scheme for payload 1 and 2: 0x01 PS1 0x10 PS2 0x11 PS3 related to time slot i
2564 trace_info.ir_trace.puncturing |= (((k+1) << 2) << (4*(3-i))) ;
2565 break ;
2566 }
2567 k++;
2568 } while (k < 3) ;
2569
2570 // EGPRS data block, Header Type 2 and 3
2571 if (macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & (1 << B_CRC_HEADER_ERROR))
2572 bsn1 = 0xffff;
2573 else
2574 {
2575 bsn1 = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 0] >> 14) & 0x03);
2576 bsn1 |= ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 1] & 0x1ff) << 2);
2577 }
2578 bsn2 = 0;
2579
2580 crc = (macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & ((1 << B_CRC_HEADER_ERROR) + (1 << B_CRC_PAYLOAD1_ERROR) + (1 << B_CRC_BLOCK_ERROR)));
2581 crc = (crc >> B_CRC_HEADER_ERROR);
2582 break;
2583
2584 case MCS7_TYPE:
2585 case MCS8_TYPE:
2586 case MCS9_TYPE:
2587 // rlc mac header type 1
2588 cps = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 2]) >> 3) & 0x1F ;
2589 do
2590 {
2591 if (cps == CPS_value7_9[j][k][mcs-MCS7_TYPE])
2592 { // set puncturing scheme for payload 1 and 2: 0x01 PS1 0x10 PS2 0x11 PS3 related to time slot i
2593 trace_info.ir_trace.puncturing |= ((((j+1) << 2) | (k+1)) << (4*(3-i))) ;
2594 break ;
2595 }
2596 k++;
2597 if (k == 3)
2598 {
2599 k = 0;
2600 j++ ;
2601 }
2602 } while (j < 3) ;
2603
2604 // EGPRS data block, Header Type 1
2605 if (macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & (1 << B_CRC_HEADER_ERROR))
2606 {
2607 bsn1 = 0xffff;
2608 bsn2 = 0xffff;
2609 }
2610 else
2611 {
2612 bsn1 = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 0] >> 14) & 0x03);
2613 bsn1 |= ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 1] & 0x1ff) << 2);
2614
2615 bsn2 = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 1] >> 9) & 0x7f);
2616 bsn2 |= ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 2] & 0x07) << 7);
2617 bsn2 += bsn1;
2618 if (bsn2 >= 2048)
2619 bsn2 -= 2048;
2620 }
2621
2622 crc = (macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & ((1 << B_CRC_HEADER_ERROR) + (1 << B_CRC_PAYLOAD1_ERROR) + (1 << B_CRC_PAYLOAD2_ERROR) + (1 << B_CRC_BLOCK_ERROR)));
2623 crc = (crc >> B_CRC_HEADER_ERROR);
2624 break;
2625
2626 default:
2627 bsn1 = 0xffff;
2628 bsn2 = 0xffff;
2629 crc = ((1 << B_CRC_HEADER_ERROR) + (1 << B_CRC_PAYLOAD1_ERROR) + (1 << B_CRC_PAYLOAD2_ERROR) + (1 << B_CRC_BLOCK_ERROR));
2630 crc = (crc >> B_CRC_HEADER_ERROR);
2631 break;
2632 }
2633
2634 // Update IR info from current PDCH
2635 trace_info.ir_trace.crc |= (crc << ((3-i)*8));
2636 trace_info.ir_trace.bsn[i] = ((bsn1 << 16) | bsn2);
2637 trace_info.ir_trace.mcs |= ((mcs << ((3-i)*8)));
2638
2639 /* we take only the msb of cv_bep and mean_bep */
2640 trace_info.ir_trace.cv_bep_egprs[i] = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][2]) >> 8) ;
2641 trace_info.ir_trace.mean_bep_egprs[i] = (macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][3]) ;
2642 if (((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & TFI_BIT_MASK) >> TFI_BIT_SHIFT) == TFI_BAD)
2643 trace_info.ir_trace.status_ir_tfi |= (0x1 << (3-i)) ; /* set tfi flag to 1 if block is not for MS */
2644 }
2645
2646 trace_info.ir_trace.fn = l1s.actual_time.fn ;
2647 trace_info.ir_trace.status_ir_tfi |= ((macs.rlc_dbl_buffer[macs.dl_buffer_index].dl_status & (1 << IR_OUT_OF_MEMORY))<<(7-IR_OUT_OF_MEMORY)) ;
2648
2649 // Output trace
2650 Trace_IR (&trace_info.ir_trace) ;
2651 }
2652 #endif //(TRACE_TYPE == 1)||(TRACE_TYPE == 4)
2653 #endif //L1_EGPRS
2654 #if TESTMODE
2655 if (l1_config.TestMode)
2656 {
2657 BOOL crc_error_bler; //Local var used for accumulating BLER
2658 UWORD8 i;
2659
2660 l1tm.tmode_stats.bler_total_blocks++;
2661 #if L1_EGPRS
2662 if (l1ps_macs_com.rlc_downlink_bufferize_param.tbf_mode == TBF_MODE_EGPRS)
2663 {
2664 for(i=0;i<macs.rlc_dbl_buffer[macs.dl_buffer_index].d_rlcmac_rx_no_gprs;i++)
2665 {
2666 //bler_total_blocks gives the total number of blocks for computing BLER
2667 //The block error is assigned to crc_error_bler.
2668 //If the block is in error bler_crc is incremented.
2669 crc_error_bler = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & (1 << B_CRC_BLOCK_ERROR)) >> B_CRC_BLOCK_ERROR);
2670 if (crc_error_bler == TRUE)
2671 l1tm.tmode_stats.bler_crc[i]++;
2672 }
2673 }
2674 else
2675 #endif
2676 {
2677 for(i=0;i<macs.rlc_dbl_buffer[macs.dl_buffer_index].d_rlcmac_rx_no_gprs;i++)
2678 {
2679 //bler_total_blocks gives the total number of blocks for computing BLER
2680 //The block error is assigned to crc_error_bler.
2681 //If the block is in error bler_crc is incremented.
2682 crc_error_bler = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_gprs[i][0] & (1 << B_CRC_BLOCK_ERROR)) >> B_CRC_BLOCK_ERROR);
2683 if (crc_error_bler == TRUE)
2684 l1tm.tmode_stats.bler_crc[i]++;
2685 }
2686 }
2687 }
2688 #endif
2689 }
2690 }
2691 // Payload still awaited
2692 else // (!rlc_downlink_copy_buffer(FALSE)
2693 {
2694 // Check spreading limit not exceeded
2695 if ((macs.tdma_delay >= 3) || (l1a_l1s_com.recovery_flag))
2696 {
2697 // Free RLC buffer
2698 macs.rlc_dbl_buffer[macs.dl_buffer_index].d_rlcmac_rx_no_gprs = RLC_BLOCK_ACK;
2699
2700 // Flag RLC call
2701 rlc_dl_call = TRUE;
2702
2703 // Dummy buffer to be reported
2704 rlc_buffer = (API*) dummy_rlc_buffer;
2705
2706 // No block reported ever by DSP
2707
2708 #if (TRACE_TYPE==5)
2709 trace_fct_simu("MACS ERROR: No RLC blocks passed to L3 on current frame", 0);
2710 sprintf(errormsg,"MACS ERROR: No RLC blocks passed to L3 on current frame");
2711 log_sim_error(ERR);
2712 #endif
2713 }
2714 else
2715 // Increment spreading counter
2716 macs.tdma_delay++;
2717 } // (!rlc_downlink_copy_buffer(FALSE)
2718
2719 // Function RLC_DOWNLINK_DATA() to be invoked
2720 if (rlc_dl_call)
2721 {
2722
2723 rlc_downlink_data( l1ps_macs_com.rlc_downlink_bufferize_param.assignment_id, // Assignment ID
2724 fn, // Frame number
2725 rlc_buffer // Pointer on the DL structure
2726 );
2727
2728 // Add the RLC_D traces in the case of EGPRS also
2729
2730 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
2731 if ((trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_RLC_PARAM)
2732 && (rlc_buffer != NULL))
2733 {
2734 UWORD8 i;
2735 UWORD16 dl_blk_status[4] = {0,0,0,0};
2736 for (i=0;i<macs.rx_no;i++)
2737 {
2738 #if (L1_EGPRS)
2739 if (l1ps_macs_com.rlc_downlink_bufferize_param.tbf_mode == TBF_MODE_EGPRS)
2740 {
2741 dl_blk_status[i] = A_DD_XGPRS[TBF_MODE_EGPRS][i][0];
2742 }
2743 else
2744 {
2745 #endif
2746 dl_blk_status[i] = (((UWORD8) NDB_PTR->a_dd_gprs[i][0]) & 0x070F);
2747 #if (L1_EGPRS)
2748 }
2749 #endif
2750 }
2751 Trace_rlc_dl_param(l1ps_macs_com.rlc_downlink_bufferize_param.assignment_id,
2752 l1s.actual_time.fn,
2753 macs.rx_no,
2754 macs.rlc_blocks_sent,
2755 macs.last_poll_response,
2756 (dl_blk_status[1]<<16) |dl_blk_status[0], //dl_blk_status for TS1 and TS0
2757 (dl_blk_status[3]<<16) |dl_blk_status[2]);//dl_blk_status for TS3 and TS2
2758 }
2759 #endif
2760 macs.rx_no = 0;
2761 l1ps_macs_com.rlc_downlink_call = FALSE;
2762 }
2763
2764 #else
2765
2766 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
2767 if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
2768 {
2769 // If some RX have been received or some TX have been programmed
2770 if ((macs.last_rx_alloc != 0) || (macs.tx_allocation != 0))
2771 {
2772 // Send trace
2773 Trace_condensed_pdtch(macs.last_rx_alloc, macs.tx_allocation);
2774 }
2775
2776 // Reset PDTCH trace structure
2777 for(i=0; i<8; i++)
2778 {
2779 trace_info.pdtch_trace.dl_status[i] = 0;
2780 trace_info.pdtch_trace.ul_status[i] = 0;
2781 }
2782 trace_info.pdtch_trace.dl_cs_type = 0;
2783 trace_info.pdtch_trace.blk_status = 0;
2784 }
2785 #endif
2786
2787
2788 // Last_poll_error processing
2789 //---------------------------
2790
2791 // All slots allocated for poll response transmission (allocated in tx_allocation
2792 // but not in tx_data) are set to 0 (no error) in last_poll_response
2793 macs.last_poll_response &= (UWORD8) (~(macs.tx_allocation) | macs.tx_data);
2794
2795 /* last_poll_response correspondance with network timeslot numbers */
2796 i = macs.old_synchro_ts - RXTX_DELAY;
2797
2798 if (i > MAX_TS_NB)
2799 {
2800 macs.last_poll_response <<= (-i);
2801 }
2802 else
2803 {
2804 macs.last_poll_response >>= i;
2805 }
2806
2807 // Store number of RX within NDB for RLC
2808 //--------------------------------------
2809
2810 NDB_PTR->d_rlcmac_rx_no_gprs = macs.rx_no;
2811
2812 #if L1_RECOVERY
2813 // blocks get a CRC error in case of COM error
2814 if (l1a_l1s_com.recovery_flag == TRUE)
2815 {
2816 // force bad CRC for 4 RX slots
2817 NDB_PTR->a_dd_gprs[0][0] |= 0x0100;
2818 NDB_PTR->a_dd_gprs[1][0] |= 0x0100;
2819 NDB_PTR->a_dd_gprs[2][0] |= 0x0100;
2820 NDB_PTR->a_dd_gprs[3][0] |= 0x0100;
2821 }
2822 #endif
2823 /******************/
2824
2825 // Call RLC_DOWNLINK
2826 //------------------
2827
2828 rlc_downlink( l1ps.read_param.assignment_id, // Assignment ID
2829 l1s.actual_time.fn, // Frame number
2830 (API*) &(NDB_PTR->d_rlcmac_rx_no_gprs), // Pointer on the DL structure
2831 macs.rlc_blocks_sent, // ID of the last transmitted uplink
2832 // data block
2833 macs.last_poll_response // Status of the poll responses of
2834 ); // the last block period
2835
2836 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
2837 if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_RLC_PARAM)
2838 {
2839 Trace_rlc_dl_param(l1ps.read_param.assignment_id,
2840 l1s.actual_time.fn,
2841 (UWORD32) &(NDB_PTR->d_rlcmac_rx_no_gprs),
2842 (UWORD8) NDB_PTR->d_rlcmac_rx_no_gprs,
2843 macs.rlc_blocks_sent,
2844 macs.last_poll_response);
2845 }
2846 #endif
2847
2848 #if TESTMODE
2849 if (l1_config.TestMode)
2850 {
2851 BOOL crc_error_bler; //Local var used for accumulating BLER
2852 UWORD8 i;
2853
2854 l1tm.tmode_stats.bler_total_blocks++;
2855
2856 for(i=0; i < macs.rx_no; i++)
2857 {
2858 //bler_total_blocks gives the total number of blocks for computing BLER
2859 //The block error is assigned to crc_error_bler.
2860 //If the block is in error bler_crc is incremented.
2861 crc_error_bler = ( (NDB_PTR->a_dd_gprs[i][0] & (1 << B_CRC_BLOCK_ERROR)) >> B_CRC_BLOCK_ERROR);
2862 if (crc_error_bler == TRUE)
2863 l1tm.tmode_stats.bler_crc[i]++;
2864 }
2865 }
2866 #endif
2867
2868 // Clear parameters
2869 //-----------------
2870
2871 /* All downlink blocks were processed */
2872 macs.last_rx_alloc = 0;
2873 macs.rx_no = 0;
2874 macs.rlc_blocks_sent = 0;
2875 macs.last_poll_response = 0;
2876
2877 l1ps_macs_com.rlc_downlink_call = FALSE;
2878
2879 // Reset CS type.
2880 //---------------
2881 #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)
2882 NDB_PTR->a_dd_gprs[0][0] = NDB_PTR->a_dd_gprs[1][0] = NDB_PTR->a_dd_gprs[2][0] =
2883 NDB_PTR->a_dd_gprs[3][0] = NDB_PTR->a_dd_gprs[4][0] = NDB_PTR->a_dd_gprs[5][0] =
2884 NDB_PTR->a_dd_gprs[6][0] = NDB_PTR->a_dd_gprs[7][0] = CS_NONE_TYPE;
2885 #else
2886 NDB_PTR->a_dd_gprs[0][0] = NDB_PTR->a_dd_gprs[1][0] = NDB_PTR->a_dd_gprs[2][0] =
2887 NDB_PTR->a_dd_gprs[3][0] = CS_NONE_TYPE;
2888 #endif
2889 #endif
2890 }//void l1ps_macs_rlc_downlink_call(void)
2891 #if FF_TBF
2892 /*-----------------------------------------------------------*/
2893 /* l1ps_macs_rlc_uplink_info() */
2894 /*-----------------------------------------------------------*/
2895 /* Parameters: */
2896 /* */
2897 /* Return: */
2898 /* */
2899 /* Description: This function is called in the */
2900 /* l1ps_macs_ctrl() function on TDMA 4, 8 or 12 */
2901 /* of MF13 */
2902 /* */
2903 /*-----------------------------------------------------------*/
2904 void l1ps_macs_rlc_uplink_info(void)
2905 {
2906 UWORD8 i;
2907
2908 #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
2909 if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
2910 {
2911 // If some RX have been received or some TX have been programmed
2912 if ((macs.last_rx_alloc != 0) || (macs.tx_allocation != 0))
2913 {
2914 // Send trace
2915 Trace_condensed_pdtch(macs.last_rx_alloc, macs.tx_allocation);
2916 }
2917
2918 // Reset PDTCH trace structure
2919 for(i=0; i<8; i++)
2920 {
2921 trace_info.pdtch_trace.dl_status[i] = 0;
2922 trace_info.pdtch_trace.ul_status[i] = 0;
2923 }
2924 trace_info.pdtch_trace.dl_cs_type = 0;
2925 trace_info.pdtch_trace.blk_status = 0;
2926 }
2927 #endif
2928
2929 // Last_poll_error processing
2930 //---------------------------
2931
2932 /* All slots allocated for poll response transmission (allocated in tx_allocation
2933 but not in tx_data) are set to 0 (no error) in last_poll_response */
2934 macs.last_poll_response &= (UWORD8) (~(macs.tx_allocation) | macs.tx_data);
2935
2936 /* last_poll_response correspondance with network timeslot numbers */
2937 i = macs.old_synchro_ts - RXTX_DELAY;
2938
2939 if (i > MAX_TS_NB)
2940 {
2941 macs.last_poll_response <<= (-i);
2942 }
2943 else
2944 {
2945 macs.last_poll_response >>= i;
2946 }
2947
2948 #if L1_EGPRS
2949 //sub_mode is ON
2950 if (l1ps_macs_com.loop_param.sub_mode == TRUE)
2951 {
2952 macs.rlc_blocks_sent = 0;
2953 macs.last_poll_response = 0;
2954 }
2955 #endif
2956
2957 rlc_uplink_info(l1ps.read_param.assignment_id,
2958 l1s.actual_time.fn,
2959 macs.rlc_blocks_sent,
2960 macs.last_poll_response);
2961
2962 //While the initialization of these variables is performed in the
2963 //l1ps_macs_rlc_downlink_call() for GPRS, for EGPRS the initialization
2964 //is done here below. Note that it is still performed on frame index 0
2965 //of MF13 in the l1s_end_manager() function whether in EGPRS or GPRS mode.
2966 //The variable below is set in the l1ps_macs_ctrl() function on frame index 2 of MF13
2967 //and stores the rx allocation. This allocation is used later in the l1ps_macs_read()
2968 //function to pass the blocks that were received in the previous block period.
2969 macs.last_rx_alloc = 0;
2970 macs.rlc_blocks_sent = 0;
2971 macs.last_poll_response = 0;
2972 }
2973
2974 /*-----------------------------------------------------------*/
2975 /* rlc_downlink_copy_buffer() */
2976 /*-----------------------------------------------------------*/
2977 /* Parameters: isr: flag that indicates whether the call */
2978 /* of this function is performed at the */
2979 /* beginning of the hisr() function */
2980 /* (hisr = TRUE) or not. */
2981 /* */
2982 /* Return: missing_payload: flag that indicates if still*/
2983 /* payloads are missing after */
2984 /* the copy */
2985 /* */
2986 /* Description: This function is called in the hisr() */
2987 /* function with hisr = TRUE and in the */
2988 /* l1ps_macs_rlc_downlink_call() function */
2989 /* with hisr = FALSE */
2990 /*-----------------------------------------------------------*/
2991 UWORD8 rlc_downlink_copy_buffer(UWORD8 isr)
2992 {
2993 BOOL missing_payload = FALSE;
2994 BOOL allocation_needed = FALSE;
2995
2996 UWORD32 i,j;
2997
2998 // Downlink blocks expected
2999 if (l1ps_macs_com.rlc_downlink_call)
3000 {
3001 // Not in TDMA3 unless we are in ISR so we may have blocks to copy
3002 if ( ((macs.tdma_delay < 3) && (!isr)) // No logical XOR in C
3003 || ((macs.tdma_delay >= 3) && (isr))
3004 )
3005
3006 {
3007 // Test buffer allocation requirement if not already allocated
3008 if (macs.dl_buffer_index == INVALID)
3009 {
3010 allocation_needed = TRUE;
3011 }
3012
3013 // Look for an available buffer and initialize it
3014 if (allocation_needed)
3015 {
3016 for (i = 0; i < NBR_SHARED_BUFFER_RLC; i++)
3017 {
3018 //as soon as one free block is found
3019 if (macs.rlc_dbl_buffer[i].d_rlcmac_rx_no_gprs == RLC_BLOCK_ACK)
3020 {
3021 // Store buffer index
3022 macs.dl_buffer_index = i;
3023 // Store number of blocks in buffer passed to RLC
3024 macs.rlc_dbl_buffer[i].d_rlcmac_rx_no_gprs = macs.rx_no;
3025 break;
3026 }
3027 }
3028 }
3029
3030 // Copy available blocks if buffer allocated
3031 if (macs.dl_buffer_index != INVALID)
3032 {
3033 // GPRS mode, no spreading
3034 #if L1_EGPRS
3035 if (l1ps_macs_com.rlc_downlink_bufferize_param.tbf_mode == TBF_MODE_GPRS)
3036 #endif
3037 {
3038 // Copy whole bunch of blocks (4 downlink, worst case)
3039 for (i=0;i<NBR_BUFFER_GPRS;i++)
3040 {
3041 memcpy((char*) &macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_gprs[i][0],
3042 (char*) A_DD_XGPRS[TBF_MODE_GPRS][i],
3043 SIZE_GPRS_DL_BUFF * sizeof(API));
3044 }
3045 }
3046 // EGPRS mode
3047 #if L1_EGPRS
3048 else
3049 {
3050 // Parse every expected block
3051 for (i = 0; i < macs.rx_no; i++)
3052 {
3053 // If not already copied
3054 if ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & CS_EGPRS_MASK) == CS_NONE_TYPE)
3055 {
3056 // New block available in API
3057 if (A_DD_XGPRS[TBF_MODE_EGPRS][i][0] & (1 << B_BLK_READY))
3058 {
3059 // Copy block from API to SRAM
3060 memcpy((char*) &macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0],
3061 (char*) A_DD_XGPRS[TBF_MODE_EGPRS][i],
3062 SIZE_EGPRS_DL_BUFF * sizeof(API));
3063
3064 // Acknowledge DSP
3065 A_DD_XGPRS[TBF_MODE_EGPRS][i][0] &= ~(1 << B_BLK_READY);
3066 }
3067 else
3068 missing_payload = TRUE;
3069 }
3070 }
3071 } // TBF mode
3072 #endif
3073
3074 // Store "missing payload" flag used for TDMA3 limit case.
3075 macs.dl_missing_payload = missing_payload;
3076
3077 } // Buffer is allocated
3078 else
3079 {
3080 // No buffer allocated yet
3081 if (allocation_needed)
3082 // RLC Buffer exhaustion - abort
3083 missing_payload = FALSE;
3084 else
3085 // No buffer allocated yet as no block present
3086 missing_payload = TRUE;
3087
3088 // Still some buffer expected
3089 macs.dl_missing_payload = TRUE;
3090 }
3091 } // Not in ISR TDMA 0,1,2, or ISR from TDMA 3
3092 else if ((macs.tdma_delay >= 3) && (!isr))
3093 {
3094 // End of L1S in TDMA3, we need to report the status from ISR call.
3095 missing_payload = macs.dl_missing_payload;
3096 }
3097
3098 // IR status reporting (relevant for EGPRS only)
3099 //----------------------------------------------
3100
3101 // RLC buffer allocated, all blocks received
3102 if ((macs.dl_buffer_index != INVALID) && (!missing_payload))
3103 {
3104 #if L1_EGPRS
3105 if ( (l1ps_macs_com.rlc_downlink_bufferize_param.tbf_mode == TBF_MODE_EGPRS)
3106 && (l1ps_dsp_com.edsp_ndb_ptr->d_modem_status_egprs & (1 << B_IR_OUT_OF_MEM)) )
3107 {
3108 // EGPRS TBF mode, IR out of memory status flag is set
3109 macs.rlc_dbl_buffer[macs.dl_buffer_index].dl_status |= (1 << IR_OUT_OF_MEMORY);
3110 }
3111 else
3112 #endif
3113 {
3114 // GPRS TBF mode or EGPRS but IR out of memory not detected
3115 macs.rlc_dbl_buffer[macs.dl_buffer_index].dl_status &= (~(1 << IR_OUT_OF_MEMORY));
3116 }
3117 }
3118 } // if (l1ps_macs_com.rlc_downlink_call)
3119
3120 // Return blocks receipt completion status
3121 return missing_payload;
3122 }
3123
3124 #endif //FF_TBF
3125
3126 #if TESTMODE
3127 //===========================================================================
3128 // Function called instead of l1ps_macs_ctrl if CMU200 loop mode is selected
3129 //===========================================================================
3130
3131 void l1ps_tmode_macs_ctrl(void)
3132 {
3133 #define NDB_PTR l1ps_dsp_com.pdsp_ndb_ptr
3134 #define SET_PTR l1pa_l1ps_com.transfer.aset
3135
3136 NDB_PTR->a_du_gprs[0][0] = l1_config.tmode.tx_params.coding_scheme;
3137
3138 /* Enable loop */
3139 NDB_PTR->d_sched_mode_gprs |= (1<<6);
3140
3141 // Force single slot allocation for CMU loop: 1RX, 1TX
3142 macs.rx_allocation = 0x80;
3143 macs.tx_allocation = 0x10;
3144 macs.tx_prach_allocation = 0;
3145 macs.pwr_allocation = 0;
3146
3147 macs.ul_buffer_index[0] = 0xFF; // UL buffer index
3148 macs.ul_buffer_index[1] = 0xFF;
3149 macs.ul_buffer_index[2] = 0xFF;
3150 macs.ul_buffer_index[3] = 0;
3151 macs.ul_buffer_index[4] = 0xFF;
3152 macs.ul_buffer_index[5] = 0xFF;
3153 macs.ul_buffer_index[6] = 0xFF;
3154 macs.ul_buffer_index[7] = 0xFF;
3155
3156 /* Disable USF management in the DSP */
3157 macs.usf_vote_enable = 0;
3158
3159 /***********************************************************/
3160 /* MAC-S control result for LAYER 1 */
3161 /***********************************************************/
3162
3163 /* We update allocation structures in Layer 1 - MAC-S interface */
3164 l1ps_macs_com.rx_allocation = macs.rx_allocation;
3165 l1ps_macs_com.tx_nb_allocation = macs.tx_allocation & (~macs.tx_prach_allocation);
3166 l1ps_macs_com.tx_prach_allocation = macs.tx_prach_allocation;
3167 l1ps_macs_com.pwr_allocation = macs.pwr_allocation;
3168
3169 /***********************************************************/
3170 /* DSP programming */
3171 /***********************************************************/
3172
3173 // Write uplink blocks - timeslots correspondance in a_ul_buffer_gprs
3174 // MAC mode in d_sched_mode_gprs and the USF table in a_usf_gprs (Each frame)
3175
3176 l1pddsp_transfer_mslot_ctrl
3177 (l1s.next_time.fn_mod13_mod4, // Burst number (0 to 3)
3178 macs.rx_allocation, // DL Bitmap
3179 macs.tx_allocation, // UL Bitmap
3180 SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_table, // USF table
3181 SET_PTR->mac_mode, // MAC mode
3182 macs.ul_buffer_index, // UL buffer index
3183 SET_PTR->tsc, // Training sequence code
3184 l1a_l1s_com.dedic_set.radio_freq, // Radio Freq. used for I/Q swap.
3185 l1a_l1s_com.dl_tn, // DL Transfer Sync. TN.
3186 #if FF_L1_IT_DSP_USF
3187 macs.dsp_usf_interrupt // USF interrupt activation
3188 #else
3189 macs.usf_vote_enable // USF vote activation
3190 #endif
3191 );
3192
3193 //NDB_PTR->a_ctrl_ched_gprs[0] = CS1_TYPE_DATA;
3194 NDB_PTR->a_ctrl_ched_gprs[0] = NDB_PTR->a_du_gprs[0][0];
3195
3196 }
3197 #endif
3198 #endif // L1_GPRS