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