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