comparison src/cs/layer1/cmacs/macs.c @ 0:4e78acac3d88

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