comparison src/cs/layer1/p_cfile/l1p_driv.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 Controle System Header *************
2 * GSM Layer 1 software
3 * L1P_DRIVE.C
4 *
5 * Filename l1p_driv.c
6 * Copyright 2003 (C) Texas Instruments
7 *
8 ************* Revision Controle System Header *************/
9
10 #define L1P_DRIVE_C
11
12 #include "l1_macro.h"
13 #include "l1_confg.h"
14
15 #if L1_GPRS
16 #if (CODE_VERSION == SIMULATION)
17 #include <string.h>
18 #include "l1_types.h"
19 #include "sys_types.h"
20 #include "l1_const.h"
21 #include "l1_time.h"
22 #if TESTMODE
23 #include "l1tm_defty.h"
24 #endif
25 #if (AUDIO_TASK == 1)
26 #include "l1audio_const.h"
27 #include "l1audio_cust.h"
28 #include "l1audio_defty.h"
29 #endif
30 #if (L1_GTT == 1)
31 #include "l1gtt_const.h"
32 #include "l1gtt_defty.h"
33 #endif
34 #if (L1_MP3 == 1)
35 #include "l1mp3_defty.h"
36 #endif
37 #if (L1_MIDI == 1)
38 #include "l1midi_defty.h"
39 #endif
40 #include "l1_defty.h"
41 #include "l1_varex.h"
42 #include "cust_os.h"
43 #include "l1_msgty.h"
44 #if L2_L3_SIMUL
45 #include "hw_debug.h"
46 #endif
47
48 #include "l1p_cons.h"
49 #include "l1p_msgt.h"
50 #include "l1p_deft.h"
51 #include "l1p_vare.h"
52 #include "l1p_tabs.h"
53
54 #include "sim_cons.h"
55 #include "sim_def.h"
56 extern T_hw FAR hw;
57 #include "l1_proto.h"
58
59 #else
60
61 #include <string.h>
62 #include "l1_types.h"
63 #include "sys_types.h"
64 #include "l1_const.h"
65 #include "l1_time.h"
66
67 #if TESTMODE
68 #include "l1tm_defty.h"
69 #endif
70 #if (AUDIO_TASK == 1)
71 #include "l1audio_const.h"
72 #include "l1audio_cust.h"
73 #include "l1audio_defty.h"
74 #endif
75 #if (L1_GTT == 1)
76 #include "l1gtt_const.h"
77 #include "l1gtt_defty.h"
78 #endif
79 #if (L1_MP3 == 1)
80 #include "l1mp3_defty.h"
81 #endif
82 #if (L1_MIDI == 1)
83 #include "l1midi_defty.h"
84 #endif
85 #include "l1_defty.h"
86 #include "l1_varex.h"
87 #include "cust_os.h"
88 #include "l1_msgty.h"
89 #if L2_L3_SIMUL
90 #include "hw_debug.h"
91 #endif
92
93 #include "l1p_cons.h"
94 #include "l1p_msgt.h"
95 #include "l1p_deft.h"
96 #include "l1p_vare.h"
97 #include "l1p_tabs.h"
98
99 #include "l1_proto.h"
100 #include "tpudrv.h"
101
102 #endif
103
104 #if(RF_FAM == 61)
105 #include "l1_rf61.h"
106 #include "tpudrv61.h"
107 #include "l1_ctl.h"
108 #endif
109
110 /*-------------------------------------------------------*/
111 /* Prototypes of external functions used in this file. */
112 /*-------------------------------------------------------*/
113 void l1dmacro_synchro (UWORD32 when, UWORD32 value);
114 void l1dmacro_offset (UWORD32 offset_value, WORD32 relative_time);
115 void l1dmacro_afc (UWORD16 afc_value, UWORD8 win_id);
116
117 #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3) || (RF_FAM == 61) )
118 UWORD16 Cust_get_pwr_data(UWORD8 txpwr, UWORD16 radio_freq
119 #if(REL99 && FF_PRF)
120 ,UWORD8 number_uplink_timeslot
121 #endif
122 );
123 #endif
124 void Cust_get_ramp_tab(API *a_ramp, UWORD8 txpwr_ramp_up, UWORD8 txpwr_ramp_down, UWORD16 radio_freq);
125
126 BOOL l1ps_swap_iq_ul (UWORD16 radio_freq);
127 BOOL l1ps_swap_iq_dl (UWORD16 radio_freq);
128 #if (L1_MADC_ON == 1)
129 #if (RF_FAM == 61)
130 void l1pdmacro_rx_up (UWORD16 radio_freq,UWORD8 adc_active, UWORD8 csf_filter_choice
131 #if (NEW_SNR_THRESHOLD == 1)
132 ,UWORD8 saic_flag
133 #endif /* NEW_SNR_THRESHOLD == 1*/
134 );
135 #endif
136 #else /* RF_FAM == 61*/
137 void l1pdmacro_rx_up (UWORD16 radio_freq);
138 #endif
139 void l1pdmacro_rx_down (UWORD16 radio_freq, UWORD8 num_rx, BOOL rx_done_flag);
140 void l1pdmacro_tx_up (UWORD16 radio_freq);
141 void l1pdmacro_tx_down (UWORD16 radio_freq, WORD16 time, BOOL tx_flag, UWORD8 timing_advance,UWORD8 adc_active);
142 void l1pdmacro_tx_synth(UWORD16 radio_freq);
143 void l1pdmacro_anchor (WORD16 time);
144
145 void l1dmacro_rx_synth(UWORD16 radio_freq);
146 void l1dmacro_agc(UWORD16 radio_freq, WORD8 agc_value, UWORD8 lna_off
147 #if (RF_FAM == 61)
148 ,UWORD8 if_ctl
149 #endif
150 );
151 #if (CODE_VERSION == SIMULATION)
152 void l1dmacro_rx_ms (UWORD16 arfcn, BOOL rxnb_select);
153 #else
154 #if (L1_MADC_ON == 1)
155 #if (RF_FAM == 61)
156 void l1dmacro_rx_ms (UWORD16 arfcn,UWORD8 adc_active);
157 #endif
158 #else
159 void l1dmacro_rx_ms (UWORD16 arfcn);
160 #endif
161 #endif
162 void l1pdmacro_it_dsp_gen(WORD16 time);
163
164 /*-------------------------------------------------------*/
165 /* Prototypes of functions defined in this file. */
166 /*-------------------------------------------------------*/
167 // TPU Drivers...
168
169
170 // DSP Drivers...
171 void l1pddsp_synchro (UWORD8 switch_mode, UWORD8 camp_timeslot);
172 void l1pddsp_idle_prach_data (BOOL polling, UWORD8 cs_type, UWORD16 channel_request_data,
173 UWORD8 bsic, UWORD16 radio_freq);
174 void l1pddsp_idle_prach_power (UWORD8 txpwr, UWORD16 radio_freq, UWORD8 ts);
175 void l1pddsp_single_tx_block (UWORD8 burst_nb, UWORD8 *data, UWORD8 tsc,
176 UWORD16 radio_freq);
177 #if FF_L1_IT_DSP_USF
178 void l1pddsp_idle_rx_nb (UWORD8 burst_nb, UWORD8 tsq, UWORD16 radio_freq,
179 UWORD8 timeslot_no, BOOL ptcch_dl, BOOL usf_interrupt);
180 #else
181 void l1pddsp_idle_rx_nb (UWORD8 burst_nb, UWORD8 tsq, UWORD16 radio_freq,
182 UWORD8 timeslot_no, BOOL ptcch_dl);
183 #endif
184 void l1pddsp_transfer_mslot_ctrl (UWORD8 burst_nb, UWORD8 dl_bitmap, UWORD8 ul_bitmap,
185 UWORD8 *usf_table, UWORD8 mac_mode, UWORD8 *ul_buffer_index,
186 UWORD8 tsc, UWORD16 radio_freq, UWORD8 synchro_timeslot,
187 #if FF_L1_IT_DSP_USF
188 UWORD8 dsp_usf_interrupt
189 #else
190 UWORD8 usf_vote_enable
191 #endif
192 );
193 void l1pddsp_transfer_mslot_power (UWORD8 *txpwr, UWORD16 radio_freq, UWORD8 ul_bitmap);
194 void l1pddsp_ul_ptcch_data (UWORD8 cs_type, UWORD16 channel_request_data, UWORD8 bsic,
195 UWORD16 radio_freq, UWORD8 timeslot_no);
196 void l1pddsp_interf_meas_ctrl (UWORD8 nb_meas_req);
197 void l1pddsp_transfer_meas_ctrl (UWORD8 meas_position);
198
199 /*-------------------------------------------------------*/
200 /* l1pd_afc() */
201 /*-------------------------------------------------------*/
202 /* Parameters : */
203 /* Return : */
204 /* Functionality : */
205 /*-------------------------------------------------------*/
206 void l1pd_afc(void)
207 {
208 #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
209 l1ddsp_load_afc(l1s.afc);
210 #endif
211 #if (RF_FAM == 61)
212 l1dtpu_load_afc(l1s.afc);
213 #endif
214 }
215
216 /*-------------------------------------------------------*/
217 /* l1pdtpu_interf_meas() */
218 /*-------------------------------------------------------*/
219 /* Parameters : */
220 /* Return : */
221 /* Functionality : */
222 /*-------------------------------------------------------*/
223 UWORD8 l1pdtpu_interf_meas(UWORD16 radio_freq,
224 WORD8 agc,
225 UWORD8 lna_off,
226 UWORD8 meas_bitmap,
227 UWORD32 offset_serv,
228 UWORD16 win_id,
229 UWORD8 synchro_ts
230 #if (RF_FAM == 61)
231 ,UWORD8 if_ctl
232 #endif
233 )
234 {
235 UWORD8 bit_mask = 0x80;
236 UWORD8 ts;
237 BOOL rf_programmed = FALSE;
238 UWORD8 count = 0;
239
240 if(!win_id)
241 {
242 // Nothing programmed yet, we must avoid Mirror effect in Ctrl phase.
243 l1pdmacro_anchor(l1_config.params.rx_change_offset_time);
244 }
245
246 for (ts=0; ts<8; ts++)
247 {
248 // the bitmap corresponds to that of the idle frame of the network!!!
249 #if ((CHIPSET==3)||(CHIPSET == 4))
250 // limitation of 5 measurements for SAMSON (TPU RAM size limitation)
251 if((meas_bitmap & bit_mask)&&(count <= 4))
252 #else
253 if(meas_bitmap & bit_mask)
254 #endif
255 {
256 UWORD16 local_win_id;
257 UWORD16 offset;
258 WORD16 when;
259 UWORD16 offset_chg;
260
261 if((ts>synchro_ts) && (count==0))
262 {
263 // The 1st Work does not contain any Interf meas.
264 // We must ovoid a possible Mirror effect for the rest of TS.
265 l1pdmacro_anchor(l1_config.params.rx_change_offset_time);
266 }
267
268 // Increment nbr of meas. programmed.
269 count++;
270
271 local_win_id = (8 - synchro_ts + ts) * BP_SPLIT;
272 if(local_win_id >= (BP_SPLIT * 8)) local_win_id -= BP_SPLIT * 8; // Modulo.
273
274 // Compute offset
275 offset_chg = ((local_win_id * BP_DURATION) >> BP_SPLIT_PW2);
276 offset = offset_serv + offset_chg;
277 if(offset >= TPU_CLOCK_RANGE) offset -= TPU_CLOCK_RANGE;
278
279 if(!rf_programmed)
280 {
281 // Compute offset change timing
282 when = offset_chg +
283 PROVISION_TIME -
284 l1_config.params.rx_synth_setup_time -
285 EPSILON_OFFS;
286
287 if(when < 0) when += TPU_CLOCK_RANGE;
288
289 // Program TPU scenario
290 l1dmacro_offset (offset, when); // change TPU offset according to win_id
291 l1dmacro_rx_synth (radio_freq); // pgme SYNTH.
292 #if (RF_FAM !=61)
293 l1dmacro_agc (radio_freq, agc,lna_off); // pgme AGC.
294 #endif
295
296 #if (RF_FAM == 61)
297 l1dmacro_agc (radio_freq, agc,lna_off, if_ctl); // pgme AGC.
298 #endif
299
300 rf_programmed = TRUE;
301 }
302 else
303 {
304 // Compute offset change timing
305 when = offset_chg - BP_DURATION + PROVISION_TIME + PW_ACQUIS_DURATION + 20;
306 if(when < 0) when += TPU_CLOCK_RANGE;
307
308 // Program TPU scenario
309 l1dmacro_offset (offset, when); // change TPU offset according to win_id
310 }
311
312 #if (CODE_VERSION == SIMULATION)
313 l1dmacro_rx_ms (radio_freq, 1); // pgm PWR acquisition.
314 #else
315 #if (L1_MADC_ON == 1)
316 #if (RF_FAM == 61)
317 l1dmacro_rx_ms (radio_freq,INACTIVE); // pgm PWR acquisition.
318 #endif
319 #else
320 l1dmacro_rx_ms (radio_freq); // pgm PWR acquisition.
321 #endif
322 #endif
323
324 l1dmacro_offset (offset_serv, IMM); // restore offset
325 }
326
327 bit_mask >>= 1;
328
329 } // for(ts...
330
331 return(count);
332 }
333
334 /*-------------------------------------------------------*/
335 /* l1dtpu_serv_rx() */
336 /*-------------------------------------------------------*/
337 /* Parameters : */
338 /* rx_id: range 0-7, first slot of RX group */
339 /* rx_group_id: used in case |RX| |RX| */
340 /* */
341 /* Return : */
342 /* Functionality : */
343 /*-------------------------------------------------------*/
344 void l1pdtpu_serv_rx_nb(UWORD16 radio_freq, UWORD8 agc, UWORD8 lna_off,
345 UWORD8 rx_id, UWORD32 offset_serv, UWORD8 num_rx,
346 UWORD8 rx_group_id, BOOL rx_done_flag,UWORD8 adc_active
347 #if (RF_FAM == 61)
348 ,UWORD8 csf_filter_choice
349 ,UWORD8 if_ctl
350 #endif
351 #if (NEW_SNR_THRESHOLD == 1)
352 ,UWORD8 saic_flag
353 #endif /* NEW_SNR_THRESHOLD*/
354 )
355 {
356 UWORD16 offset;
357
358 #if (CODE_VERSION == SIMULATION)
359 UWORD32 tpu_w_page;
360
361 if (hw.tpu_r_page==0)
362 tpu_w_page=1;
363 else
364 tpu_w_page=0;
365
366 hw.rx_id[tpu_w_page][rx_group_id-1]=rx_id;
367 hw.num_rx[tpu_w_page][rx_group_id-1]=num_rx;
368 hw.rx_group_id[tpu_w_page]=rx_group_id;
369 #endif
370
371 offset = offset_serv + (rx_id * BP_DURATION);
372 if(offset >= TPU_CLOCK_RANGE) offset -= TPU_CLOCK_RANGE;
373
374 if (rx_group_id == 1)
375 {
376 // Time tracking.
377 l1dmacro_synchro (l1_config.params.rx_change_synchro_time, offset_serv); // Adjust serving OFFSET.
378
379 #if L2_L3_SIMUL
380 #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET)
381 buffer_trace(3, 0x43, offset_serv, l1s.actual_time.fn, 0);
382 #endif
383 #endif
384
385 // Change offset to align on RX.
386 l1dmacro_offset(offset, IMM);
387
388 // Program Synth.
389 // Program ADC measurement
390 // Program AGC.
391 l1dmacro_rx_synth(radio_freq);
392 if(adc_active == ACTIVE)
393 l1dmacro_adc_read_rx();
394
395 l1dmacro_agc (radio_freq, agc, lna_off
396 #if (RF_FAM == 61)
397 ,if_ctl
398 #endif
399 );
400 }
401 else
402 {
403 // Change offset to align on RX.
404 l1dmacro_offset(offset, IMM); // Change offset to align on RX.
405 }
406
407 l1pdmacro_rx_up (radio_freq
408 #if (RF_FAM == 61)
409 ,adc_active
410 ,csf_filter_choice
411 #endif
412 #if (NEW_SNR_THRESHOLD == 1)
413 ,saic_flag
414 #endif /* NEW_SNR_THRESHOLD*/
415
416 ); // RX window opened.
417 l1pdmacro_rx_down(radio_freq, num_rx, rx_done_flag); // RX window closed.
418
419 // Restore offset to synchro value.
420 l1dmacro_offset (offset_serv, IMM);
421 }
422
423 /*-------------------------------------------------------*/
424 /* l1dtpu_serv_tx() */
425 /*-------------------------------------------------------*/
426 /* Parameters : */
427 /* Return : */
428 /* Functionality : */
429 /*-------------------------------------------------------*/
430 #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
431 #ifndef ABB_RAMP_UP_TIME //Flexi ABB Delays defines it in tpudrvXX.h
432 #define ABB_RAMP_UP_TIME 32 // maximum time for ramp up
433 #endif
434
435 #ifndef ABB_RAMP_DELAY//Flexi ABB Delays defines it in tpudrvXX.h
436 #define ABB_RAMP_DELAY 6 // minimum ramp delay APCDEL
437 #endif
438
439 #ifndef ABB_BULON_HOLD_TIME //Flexi ABB Delays defines it in tpudrvXX.h
440 #define ABB_BULON_HOLD_TIME 32 // min. hold time for BULON after BULENA down
441 #endif
442
443
444 #endif
445 void l1pdtpu_serv_tx(UWORD16 radio_freq,
446 UWORD8 timing_advance,
447 UWORD32 offset_serv,
448 UWORD8 tx_id,
449 UWORD8 num_tx,
450 UWORD8 tx_group_id,
451 UWORD8 switch_flag,
452 BOOL burst_type,
453 BOOL rx_flag,
454 UWORD8 adc_active)
455 {
456 WORD16 time;
457 UWORD32 offset_tx;
458 UWORD32 timing_advance_in_qbit = (UWORD32)timing_advance << 2;
459 #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3) || (RF_FAM == 61))
460 UWORD16 apcdel1_data, apcdel1_data_up;
461 #endif
462 UWORD8 i;
463 static UWORD8 static_switch_flag = 0;
464
465 #if (CODE_VERSION == SIMULATION)
466 UWORD32 tpu_w_page;
467
468 if (hw.tpu_r_page==0)
469 tpu_w_page=1;
470 else
471 tpu_w_page=0;
472
473 hw.tx_id[tpu_w_page][tx_group_id-1]=tx_id;
474 hw.num_tx[tpu_w_page][tx_group_id-1]=num_tx;
475 hw.tx_group_id[tpu_w_page]=tx_group_id;
476 #endif
477
478 // Reset timing advance if TA_ALGO not enabled.
479 #if !TA_ALGO
480 timing_advance_in_qbit = 0;
481 #endif
482
483 // In case another group of TX bursts is called, the previous slot was a hole
484 // An IT has to be generated to the DSP so that ramps and power level are reloaded
485 // This does not apply to combinations of PRACH and TX NB
486 if ((tx_group_id > 1) && (!static_switch_flag))
487 {
488 // exact timing for generation of IT during hole not required but
489 // time > time of previous ramp down (BULENA -> BULON down = 32 qb) + margin (10 qb)
490 #if (RF_FAM != 61)
491 time = TX_TABLE[tx_id-1] + PROVISION_TIME + ABB_BULON_HOLD_TIME + 10
492 - l1_config.params.prg_tx_gsm;
493 #endif
494
495 #if (RF_FAM == 61)
496 time = TX_TABLE[tx_id-1] + PROVISION_TIME + APC_RAMP_DOWN_TIME + 10
497 - l1_config.params.prg_tx_gsm;
498 #endif
499
500 if (burst_type == TX_NB_BURST)
501 time -= timing_advance_in_qbit; // time can never be negative here
502
503 l1pdmacro_it_dsp_gen(time);
504 }
505
506
507 if (tx_group_id == 1)
508 {
509 #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
510 //MS TX, set ABB in MS mode
511 #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37)
512 // ABB set to MS mode if |TX|TX|.., |TX|PRACH|, |PRACH|TX| or |PRACH|PRACH|
513 // switch_flag is set for the first burst of TX/PRACH or PRACH/PRACH combinations
514 // MS mode in ABB must be maintained for second burst (static_switch_flag)
515 if ((num_tx > 1) || (switch_flag) || (static_switch_flag))
516 l1ps_dsp_com.pdsp_ndb_ptr->d_bbctrl_gprs = l1_config.params.bbctrl | B_MSLOT;
517 else
518 l1ps_dsp_com.pdsp_ndb_ptr->d_bbctrl_gprs = l1_config.params.bbctrl;
519 #endif
520 #endif
521 }
522 else
523 {
524 // handle special case |TX| |TX|TX|
525 #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
526 //MS TX, set ABB in MS mode
527 #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37)
528 if ((num_tx > 1) || (switch_flag) || (static_switch_flag))
529 l1ps_dsp_com.pdsp_ndb_ptr->d_bbctrl_gprs = l1_config.params.bbctrl | B_MSLOT;
530 #endif
531 #endif
532 }
533
534 // Compute offset value for TX.
535 // PRG_TX has become variable, no longer contained in TIME_OFFSET_TX !
536 if ((burst_type == TX_NB_BURST) || (switch_flag==1))
537 {
538 offset_tx = offset_serv + TX_TABLE[tx_id] + PROVISION_TIME
539 - l1_config.params.prg_tx_gsm - timing_advance_in_qbit;
540 }
541 else
542 {
543 offset_tx = offset_serv + TX_TABLE[tx_id] + PROVISION_TIME
544 - l1_config.params.prg_tx_gsm;
545 }
546
547 // offset_tx mod 5000
548 if (offset_tx >= TPU_CLOCK_RANGE)
549 offset_tx -= TPU_CLOCK_RANGE;
550
551 if(rx_flag == TRUE)
552 {
553 time = offset_tx -
554 l1_config.params.tx_synth_setup_time -
555 EPSILON_OFFS
556 - offset_serv;
557 if ((burst_type == TX_NB_BURST) || (switch_flag==1))
558 time += timing_advance_in_qbit - TA_MAX;
559 }
560 else
561 time = TPU_CLOCK_RANGE - EPSILON_SYNC;
562
563 if (time < 0)
564 time += TPU_CLOCK_RANGE;
565
566 if (!static_switch_flag)
567 l1dmacro_offset (offset_tx, (WORD32) time); // load OFFSET for TX before each burst.
568
569 #if L2_L3_SIMUL
570 #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET)
571 buffer_trace(2, offset_tx,l1s.actual_time.fn,0,0);
572 #endif
573 #endif
574
575 time=0;
576
577 // program PLL only if no TX control carried out in same frame: |TX| |TX|TX| possible
578 // |PRACH|TX|, |TX|PRACH| or |PRACH|PRACH| also possible
579 if (tx_group_id == 1)
580 {
581 l1pdmacro_tx_synth(radio_freq); // load SYNTH.
582 }
583
584 if (!static_switch_flag) // window opened for previous time slot (TX/PRACH or PRACH/PRACH)
585 l1pdmacro_tx_up(radio_freq); // TX window opened
586
587
588 #if (CODE_VERSION == SIMULATION)
589 if (burst_type == TX_RA_BURST)
590 {
591 time += l1_config.params.tx_ra_duration;
592 }
593 else
594 {
595 if (num_tx > 1)
596 // num_tx * BP_DURATION
597 time += TX_TABLE[num_tx - 1] + l1_config.params.tx_nb_duration;
598 else
599 time += l1_config.params.tx_nb_duration;
600 }
601 #else
602 #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
603 // Read APCDEL1 register DELU(4:0): delay of ramp up start, DELD (9:5) delay of ramp down start
604 // This value is used for computations in MS TX or TX/PRACH combinations
605 // This value is not modified by the computations
606 apcdel1_data = (l1s_dsp_com.dsp_ndb_ptr->d_apcdel1 >> 6) & 0x03ff;
607 apcdel1_data_up = apcdel1_data & 0x001f; //delay of ramp up start
608 #endif
609
610 #if (RF_FAM == 61)
611 // Read APCDEL1 register DELU(4:0): delay of ramp up start, DELD (9:5) delay of ramp down start
612 // This value is used for computations in MS TX or TX/PRACH combinations
613 // This value is not modified by the computations
614 apcdel1_data = (l1s_dsp_com.dsp_ndb_ptr->d_apcdel1) & 0x03ff;
615 apcdel1_data_up = apcdel1_data & 0x001f; //delay of ramp up start
616 #endif
617
618 if (!switch_flag)
619 {
620 if (burst_type == TX_NB_BURST)
621 {
622 // If PRACH precedes TX normal burst(s) we have to add BP_DURATION
623 if (static_switch_flag)
624 time += BP_DURATION;
625
626 // generate DSP IT for each TX slot after ramp up
627 // Margin:
628 // ABB_RAMP_DELAY = 4*1.5bits internal ABB delay BULENA ON -> ramp up
629 // apcdel1_data_up = additional delay BULENA ON -> ramp up
630 // ABB_RAMP_UP_TIME: maximum time for ramp up: 16 coeff.
631 // 10 qbits of additional margin
632 #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
633 for (i=0; i<num_tx; i++)
634 l1pdmacro_it_dsp_gen(time + ABB_RAMP_DELAY + ABB_RAMP_UP_TIME + i*BP_DURATION + apcdel1_data_up + 10);
635 #endif
636
637 #if (RF_FAM == 61)
638 for (i=0; i<num_tx; i++)
639 l1pdmacro_it_dsp_gen(time + APC_RAMP_DELAY + APC_RAMP_UP_TIME + i*BP_DURATION + apcdel1_data_up + 10);
640 #endif
641
642
643 if (num_tx > 1)
644 // (num_tx - 1) * BP_DURATION + normal burst duration
645 time += TX_TABLE[num_tx - 1] + l1_config.params.tx_nb_duration - (num_tx - 1);
646 else
647 time += l1_config.params.tx_nb_duration;
648 }
649 else //PRACH
650 {
651 // If TX NB precedes PRACH we have to add BP_DURATION and TA (in qbits)
652 if (static_switch_flag == 1)
653 {
654 if (timing_advance_in_qbit > 240) // clip TA, cf. comment below
655 timing_advance_in_qbit = 240;
656 time += BP_DURATION + timing_advance_in_qbit;
657 }
658 // If PRACH precedes PRACH we have to add BP_DURATION
659 else if (static_switch_flag == 2)
660 time += BP_DURATION ;
661
662 #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
663 l1pdmacro_it_dsp_gen(time + ABB_RAMP_DELAY + ABB_RAMP_UP_TIME + apcdel1_data_up + 10);
664 #endif
665
666 #if (RF_FAM == 61)
667 l1pdmacro_it_dsp_gen(time + APC_RAMP_DELAY + APC_RAMP_UP_TIME + apcdel1_data_up + 10);
668 #endif
669
670 time += l1_config.params.tx_ra_duration;
671 }
672
673 }
674 else if (switch_flag == 1) // |TX|PRACH| or |PRACH|TX|
675 {
676 #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)
677 // => ABB windows are opened as for TX_NB in MS mode
678 // => Ramp up start of PRACH is delayed inside this window by the TA of the TX_NB
679 // => DSP inserts dummy bits such that ramp and modulation match
680 // Rem.: the TA passed for the PRACH is the one for the following TX_NB!!!
681 #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3)) || (RF_FAM == 61)
682 // In combinations of TX_NB and PRACH apcdel1_bis and apcdel2_bis apply to the PRACH
683 UWORD16 apcdel1_bis_data, apcdel1_bis_data_up, apcdel2_bis_data_up, prach_delay;
684 API d_ctrl_abb_gprs;
685
686 // clip TA (in qbit): max. TA supported = BP_DURATION - PRACH duration - max. ramp time
687 // = 625 - 88*4 - 32 = 241
688 if (timing_advance_in_qbit > 240)
689 timing_advance_in_qbit = 240;
690
691 prach_delay = apcdel1_data_up + timing_advance_in_qbit;
692 apcdel1_bis_data_up = prach_delay & 0x001f;
693 apcdel2_bis_data_up = (prach_delay >> 5) & 0x001f;
694
695 // For ramp down delay we need to keep the original value from APCDEL1 (bits 9:5)
696 // APCDEL2 default value is '0'
697 apcdel1_bis_data = apcdel1_bis_data_up | (apcdel1_data & 0x03e0);
698
699 #if(RF_FAM != 61)
700 l1s_dsp_com.dsp_ndb_ptr->d_apcdel1_bis = (apcdel1_bis_data << 6) | 0x04;
701 l1s_dsp_com.dsp_ndb_ptr->d_apcdel2_bis = (apcdel2_bis_data_up << 6) | 0x34;
702 #else
703 l1s_dsp_com.dsp_ndb_ptr->d_apcdel1_bis = (apcdel1_bis_data );
704 l1s_dsp_com.dsp_ndb_ptr->d_apcdel2_bis = (apcdel2_bis_data_up);
705 #endif
706
707 if (burst_type == TX_RA_BURST) // |PRACH|TX|
708 {
709
710 #if(RF_FAM != 61)
711 l1pdmacro_it_dsp_gen(time + ABB_RAMP_DELAY + ABB_RAMP_UP_TIME + prach_delay + 10);
712 #else
713 l1pdmacro_it_dsp_gen(time + APC_RAMP_DELAY + APC_RAMP_UP_TIME + prach_delay + 10);
714 #endif
715 // apcdel1_bis, apcdel2_bis must be programmed for the current ts (PRACH)
716 // here we need to overwrite (mask) bits for APCDEL1, APCDEL2 programming done in l1pddsp_transfer_mslot_power()
717 d_ctrl_abb_gprs = l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[tx_id];
718 d_ctrl_abb_gprs |= ((1 << B_BULRAMPDEL_BIS) | (1 << B_BULRAMPDEL2_BIS));
719 d_ctrl_abb_gprs &= ~((1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2));
720 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[tx_id] = d_ctrl_abb_gprs;
721 }
722 else // |TX|PRACH|
723 {
724 #if(RF_FAM != 61)
725 l1pdmacro_it_dsp_gen(time + ABB_RAMP_DELAY + ABB_RAMP_UP_TIME + apcdel1_data_up + 10);
726 #else
727 l1pdmacro_it_dsp_gen(time + APC_RAMP_DELAY + APC_RAMP_UP_TIME + apcdel1_data_up + 10);
728 #endif
729
730 // apcdel1_bis, apcdel2_bis must be programmed for the next ts (PRACH)
731 d_ctrl_abb_gprs = l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[tx_id + 1];
732 d_ctrl_abb_gprs |= ((1 << B_BULRAMPDEL_BIS) | (1 << B_BULRAMPDEL2_BIS));
733 d_ctrl_abb_gprs &= ~((1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2));
734 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[tx_id + 1] = d_ctrl_abb_gprs;
735 }
736 #endif // ANALOG
737
738 static_switch_flag = 1;
739
740 #endif // DSP == 33 || DSP == 34 || (DSP == 36) || (DSP == 37)
741 }
742 else if (switch_flag == 2) // |PRACH|PRACH|
743 // Combination handled by programming ABB with MS mode = 1
744 // => first burst length of first PRACH = BP_DURATION
745 {
746 #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
747 l1pdmacro_it_dsp_gen(time + ABB_RAMP_DELAY + ABB_RAMP_UP_TIME + apcdel1_data_up + 10);
748 #endif
749
750 #if (RF_FAM == 61)
751 l1pdmacro_it_dsp_gen(time + APC_RAMP_DELAY + APC_RAMP_UP_TIME + apcdel1_data_up + 10);
752 #endif
753
754 static_switch_flag = 2;
755 }
756 #endif //Codeversion
757
758 // In case of combinations TX_NB/PRACH or PRACH/PRACH the TX window is kept open
759 if (!switch_flag)
760 {
761 l1pdmacro_tx_down(radio_freq, time, switch_flag, timing_advance_in_qbit,adc_active); // TX window closed
762
763 l1dmacro_offset (offset_serv, IMM); // Restore offset with serving value.
764
765 static_switch_flag = 0;
766 }
767
768 #if L2_L3_SIMUL
769 #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET)
770 buffer_trace(2, offset_serv,l1s.actual_time.fn,0,0);
771 #endif
772 #endif
773 }
774
775 /*-------------------------------------------------------*/
776 /* l1pddsp_synchro() */
777 /*-------------------------------------------------------*/
778 /* Parameters : */
779 /* Return : */
780 /* Functionality : */
781 /*-------------------------------------------------------*/
782 void l1pddsp_synchro(UWORD8 switch_mode, UWORD8 camp_timeslot)
783 {
784 // Set "b_abort" to TRUE.
785 l1s_dsp_com.dsp_db_w_ptr->d_ctrl_system |= (1 << B_TASK_ABORT);
786
787 // Set switch mode within "b_switch_to_gprs" & "b_switch_to_gms"
788 l1ps_dsp_com.pdsp_ndb_ptr->d_sched_mode_gprs = (switch_mode << B_SWITCH);
789
790 // In case of a switch to GPRS_SCHEDULER, last_used_txpwr is set to "NO_TXPWR"
791 // in order to force GSM ramp programming when the MS will switch back to
792 // GSM_SCHEDULER
793 // Moreover, the d_win_start_gprs register must be initialized only during the
794 // GSM->GPRS switch too.
795 if(switch_mode == GPRS_SCHEDULER)
796 {
797 l1s.last_used_txpwr = NO_TXPWR;
798
799 // Set camp timeslot.
800 l1ps_dsp_com.pdsp_ndb_ptr->d_win_start_gprs = camp_timeslot;
801 }
802 }
803
804
805 /*-------------------------------------------------------*/
806 /* l1pddsp_idle_prach_data() */
807 /*-------------------------------------------------------*/
808 /* Parameters : */
809 /* Return : */
810 /* Functionality : */
811 /*-------------------------------------------------------*/
812 void l1pddsp_idle_prach_data(BOOL polling,
813 UWORD8 cs_type,
814 UWORD16 channel_request_data,
815 UWORD8 bsic,
816 UWORD16 radio_freq)
817 {
818 UWORD16 swap_bit; // 16 bit wide to allow shift left.
819
820 // UL on TS=3.
821 l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= 0x80 >> 3;
822
823 // Swap I/Q management.
824 swap_bit = l1ps_swap_iq_ul(radio_freq);
825 l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= swap_bit << 15;
826
827 // Load UL buffer according to "polling" bit.
828 if(polling)
829 {
830 // Select first UL polling buffer.
831 l1ps_dsp_com.pdsp_ndb_ptr->a_ul_buffer_gprs[3] = 8;
832
833 // Store CS type.
834 l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[0][0] = cs_type;
835
836 // Store UL data block.
837 if(cs_type == CS_PAB8_TYPE)
838 {
839 l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[0][2] = ((API)(bsic << 2)) |
840 ((API)(channel_request_data) << 8);
841 l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[0][3] = 0;
842 }
843 else
844 {
845 l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[0][2] = ((API)(channel_request_data) << 5);
846 l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[0][3] = ((API)(bsic << 10));
847 }
848 }
849 else
850 {
851 // Set "b_access_prach" to indicate 1 Prach only to DSP.
852 l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= (1 << B_ACCESS_PRACH);
853
854 // Select first UL data buffer.
855 l1ps_dsp_com.pdsp_ndb_ptr->a_ul_buffer_gprs[3] = 0;
856
857 // Store CS type.
858 l1ps_dsp_com.pdsp_ndb_ptr->a_du_gprs[0][0] = cs_type;
859
860 // Store UL data block.
861 if(cs_type == CS_PAB8_TYPE)
862 {
863 l1ps_dsp_com.pdsp_ndb_ptr->a_du_gprs[0][1] = ((API)(bsic << 2)) |
864 ((API)(channel_request_data) << 8);
865 l1ps_dsp_com.pdsp_ndb_ptr->a_du_gprs[0][2] = 0;
866 }
867 else
868 {
869 l1ps_dsp_com.pdsp_ndb_ptr->a_du_gprs[0][1] = ((API)(channel_request_data) << 5);
870 l1ps_dsp_com.pdsp_ndb_ptr->a_du_gprs[0][2] = ((API)(bsic << 10));
871 }
872
873 if (l1pa_l1ps_com.pra_info.prach_alloc == FIX_PRACH_ALLOC)
874 {
875 // Set fix alloc bit.
876 l1ps_dsp_com.pdsp_ndb_ptr->d_sched_mode_gprs |= (2 << B_MAC_MODE);
877 }
878 else
879 {
880 // Reset MAC mode to dynamic allocation
881 l1ps_dsp_com.pdsp_ndb_ptr->d_sched_mode_gprs &= ~(3 << B_MAC_MODE);
882
883 #if !FF_L1_IT_DSP_USF
884 #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)
885 // Enable USF vote on timeslot 0
886 l1ps_dsp_com.pdsp_ndb_ptr->d_usf_vote_enable = 0x80;
887 #endif
888 #endif
889 }
890 }
891 }
892
893 /*-------------------------------------------------------*/
894 /* l1pddsp_idle_prach_power() */
895 /*-------------------------------------------------------*/
896 /* Parameters : */
897 /* Return : */
898 /* Functionality : */
899 /*-------------------------------------------------------*/
900 void l1pddsp_idle_prach_power(UWORD8 txpwr,
901 UWORD16 radio_freq,
902 UWORD8 ts)
903 {
904 #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3) || (RF_FAM == 61))
905 UWORD16 pwr_data;
906 #endif
907
908 #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3) )
909 // Force FIXED transmit power if requested.
910 if(l1_config.tx_pwr_code == 0)
911 {
912 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_power_gprs[ts] = l1_config.params.fixed_txpwr;
913
914 // Control bitmap: update RAMP, use RAMP[5][..].
915 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[ts] =
916 ((1 << B_RAMP_GPRS) | (5 << B_RAMP_NB_GPRS) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2));
917
918 // Store Ramp.
919 #if (CODE_VERSION != SIMULATION)
920 Cust_get_ramp_tab(l1ps_dsp_com.pdsp_ndb_ptr->a_ramp_gprs[5],
921 0, /* not used */
922 0, /* not used */
923 1 /* arbitrary value for arfcn */ );
924 #endif
925 }
926 else
927 {
928 // Get H/W value corresponding to txpwr command.
929 pwr_data = Cust_get_pwr_data(txpwr, radio_freq
930 #if(REL99 && FF_PRF)
931 ,1
932 #endif
933 );
934
935 // Store Transmit power.
936 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_power_gprs[ts] = ((pwr_data << 6) | 0x12);
937
938 // Control bitmap: update RAMP, use RAMP[5][..].
939 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[ts] = ((1 << B_RAMP_GPRS) | (5 << B_RAMP_NB_GPRS) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2));
940
941 // Store Ramp.
942 #if (CODE_VERSION != SIMULATION)
943 Cust_get_ramp_tab(&(l1ps_dsp_com.pdsp_ndb_ptr->a_ramp_gprs[5][0]), txpwr, txpwr, radio_freq);
944 #endif
945 }
946 #endif
947
948 #if (RF_FAM == 61)
949 // Force FIXED transmit power if requested.
950 if(l1_config.tx_pwr_code == 0)
951 {
952 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_power_gprs[ts] = l1_config.params.fixed_txpwr;
953
954 // Control bitmap: update RAMP, use RAMP[5][..].
955 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[ts] =
956 ((1 << B_RAMP_GPRS) | (5 << B_RAMP_NB_GPRS) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2));
957
958 // Store Ramp.
959 #if (DSP ==38) || (DSP == 39)
960 Cust_get_ramp_tab(l1ps_dsp_com.pdsp_ndb_ptr->a_drp_ramp2_gprs[5],
961 0, /* not used */
962 0, /* not used */
963 1 /* arbitrary value for arfcn */ );
964 #endif
965 }
966 else
967 {
968 // Get H/W value corresponding to txpwr command.
969 pwr_data = Cust_get_pwr_data(txpwr, radio_freq
970 #if(REL99 && FF_PRF)
971 ,1
972 #endif
973 );
974
975 // Store Transmit power.
976 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_power_gprs[ts] = (API) (pwr_data);
977
978 // Control bitmap: update RAMP, use RAMP[5][..].
979 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[ts] = ((1 << B_RAMP_GPRS) | (5 << B_RAMP_NB_GPRS) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2));
980
981 // Store Ramp.
982 #if(DSP == 38) || (DSP == 39)
983 Cust_get_ramp_tab(&(l1ps_dsp_com.pdsp_ndb_ptr->a_drp_ramp2_gprs[5][0]), txpwr, txpwr, radio_freq);
984 #endif
985 }
986 #endif //RF_FAM == 61
987
988 }
989
990 /*-------------------------------------------------------*/
991 /* l1pddsp_single_block() */
992 /*-------------------------------------------------------*/
993 /* Parameters : */
994 /* Return : */
995 /* Functionality : */
996 /*-------------------------------------------------------*/
997 void l1pddsp_single_tx_block(UWORD8 burst_nb,
998 UWORD8 *data,
999 UWORD8 tsc,
1000 UWORD16 radio_freq)
1001 {
1002 UWORD16 swap_bit; // 16 bit wide to allow shift left.
1003
1004 // Burst number within a block.
1005 l1ps_dsp_com.pdsp_db_w_ptr->d_burst_nb_gprs = burst_nb;
1006
1007 // UL on TS=3.
1008 l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= 0x80 >> 3;
1009
1010 // Swap I/Q management.
1011 swap_bit = l1ps_swap_iq_ul(radio_freq);
1012 l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= swap_bit << 15;
1013
1014 // Select first UL polling buffer.
1015 l1ps_dsp_com.pdsp_ndb_ptr->a_ul_buffer_gprs[3] = 8;
1016
1017 // Store CS type: CS1 for Polling.
1018 l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[0][0] = CS1_TYPE_POLL;
1019
1020 if(burst_nb == BURST_1)
1021 // Store UL data block.
1022 {
1023 API *ul_block_ptr = &(l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[0][2]);
1024 UWORD8 i,j;
1025
1026 // Copy first 22 bytes in the first 11 words after header.
1027 for (i=0, j=0; j<11; j++)
1028 {
1029 ul_block_ptr[j] = ((API)(data[i])) | ((API)(data[i+1]) << 8);
1030 i += 2;
1031 }
1032 // Copy last UWORD8 (23rd) in the 12th word after header.
1033 ul_block_ptr[11] = data[22];
1034 }
1035
1036 // Training sequence.
1037 // Rem: bcch_freq_ind is set within Hopping algo.
1038 l1s_dsp_com.dsp_db_w_ptr->d_ctrl_system |= tsc << B_TSQ;
1039 }
1040
1041 /*-------------------------------------------------------*/
1042 /* l1pddsp_idle_rx_nb() */
1043 /*-------------------------------------------------------*/
1044 /* Parameters : */
1045 /* Return : */
1046 /* Functionality : */
1047 /*-------------------------------------------------------*/
1048 #if FF_L1_IT_DSP_USF
1049 void l1pddsp_idle_rx_nb(UWORD8 burst_nb,
1050 UWORD8 tsc,
1051 UWORD16 radio_freq,
1052 UWORD8 timeslot_no,
1053 BOOL ptcch_dl,
1054 BOOL usf_interrupt)
1055 #else
1056 void l1pddsp_idle_rx_nb(UWORD8 burst_nb,
1057 UWORD8 tsc,
1058 UWORD16 radio_freq,
1059 UWORD8 timeslot_no,
1060 BOOL ptcch_dl)
1061 #endif
1062 {
1063 UWORD16 swap_bit; // 16 bit wide to allow shift left.
1064
1065 // DL on TS=0.
1066 l1ps_dsp_com.pdsp_db_w_ptr->d_task_d_gprs |= 0x80 >> timeslot_no;
1067
1068 // Swap I/Q management.
1069 swap_bit = l1ps_swap_iq_dl(radio_freq);
1070 l1ps_dsp_com.pdsp_db_w_ptr->d_task_d_gprs |= swap_bit << 15;
1071
1072 if(ptcch_dl)
1073 {
1074 // PTCCH/DL case must be flagged to DSP.
1075 l1ps_dsp_com.pdsp_db_w_ptr->d_task_d_gprs |= (1 << B_PTCCH_DL);
1076 }
1077
1078 // Burst number within a block.
1079 l1ps_dsp_com.pdsp_db_w_ptr->d_burst_nb_gprs = burst_nb;
1080
1081 // Channel coding is forced to CS1.
1082 l1ps_dsp_com.pdsp_ndb_ptr->a_ctrl_ched_gprs[timeslot_no] = CS1_TYPE_DATA;
1083
1084 // pass information to DSP which good USF value is to be expected
1085 l1ps_dsp_com.pdsp_ndb_ptr->a_usf_gprs[0] = (API) 0x07;
1086
1087 #if FF_L1_IT_DSP_USF
1088 // In case of connection establishment mode with dynamic or fixed
1089 // allocation scheme we need to request the DSP USF interrupt for PRACH
1090 // scheduling. Latched by DSP during Work3
1091 if (burst_nb == 3)
1092 {
1093 if (usf_interrupt)
1094 l1ps_dsp_com.pdsp_ndb_ptr->d_usf_vote_enable |= (1 << B_USF_IT);
1095 else
1096 l1ps_dsp_com.pdsp_ndb_ptr->d_usf_vote_enable &= ~(1 << B_USF_IT);
1097 }
1098 #endif
1099
1100 // RIF receiver algorithm: select 156.25.
1101 l1ps_dsp_com.pdsp_ndb_ptr->d_sched_mode_gprs &= 0xFFFF ^ (1 << B_RIF_RX_MODE);
1102
1103 // Training sequence.
1104 // Rem: bcch_freq_ind is set within Hopping algo.
1105 l1s_dsp_com.dsp_db_w_ptr->d_ctrl_system |= tsc << B_TSQ;
1106
1107 }
1108
1109
1110 /*-------------------------------------------------------*/
1111 /* l1pddsp_transfer_mslot_ctrl() */
1112 /*-------------------------------------------------------*/
1113 /* Parameters : */
1114 /* Return : */
1115 /* Functionality : */
1116 /*-------------------------------------------------------*/
1117 void l1pddsp_transfer_mslot_ctrl(UWORD8 burst_nb,
1118 UWORD8 dl_bitmap,
1119 UWORD8 ul_bitmap,
1120 UWORD8 *usf_table,
1121 UWORD8 mac_mode,
1122 UWORD8 *ul_buffer_index,
1123 UWORD8 tsc,
1124 UWORD16 radio_freq,
1125 UWORD8 synchro_timeslot,
1126 #if FF_L1_IT_DSP_USF
1127 UWORD8 dsp_usf_interrupt
1128 #else
1129 UWORD8 usf_vote_enable
1130 #endif
1131 )
1132 {
1133 UWORD8 i;
1134 UWORD16 swap_bit; // 16 bit wide to allow shift left.
1135
1136 // Burst number within a block.
1137 l1ps_dsp_com.pdsp_db_w_ptr->d_burst_nb_gprs = burst_nb;
1138
1139 // DL bitmap.
1140 l1ps_dsp_com.pdsp_db_w_ptr->d_task_d_gprs = dl_bitmap;
1141
1142 // UL bitmap.
1143 l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs = ul_bitmap;
1144
1145 // Swap I/Q management for DL.
1146 swap_bit = l1ps_swap_iq_dl(radio_freq);
1147 l1ps_dsp_com.pdsp_db_w_ptr->d_task_d_gprs |= swap_bit << 15;
1148
1149 // Swap I/Q management for UL.
1150 swap_bit = l1ps_swap_iq_ul(radio_freq);
1151 l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= swap_bit << 15;
1152
1153 if(burst_nb == 0)
1154 {
1155 // Store USF table
1156 for(i=0;i<(8 - synchro_timeslot);i++)
1157 l1ps_dsp_com.pdsp_ndb_ptr->a_usf_gprs[i] = usf_table[i+synchro_timeslot];
1158
1159 // Automatic CS detection.
1160 for(i=0;i<8;i++)
1161 {
1162 l1ps_dsp_com.pdsp_ndb_ptr->a_ctrl_ched_gprs[i] = CS_AUTO_DETECT;
1163
1164 // Select first UL polling buffer.
1165 l1ps_dsp_com.pdsp_ndb_ptr->a_ul_buffer_gprs[i] = ul_buffer_index[i];
1166 }
1167
1168 #if !FF_L1_IT_DSP_USF
1169 // USF vote enable programming
1170
1171 #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)
1172 // Multislot TX allowed and usf_vote_enable suported: programs usf_vote_enable
1173 l1ps_dsp_com.pdsp_ndb_ptr->d_usf_vote_enable = usf_vote_enable;
1174 #else
1175 // Single slot TX only and usf_vote_enable not supported
1176 // Modify MAC mode
1177 if (usf_vote_enable)
1178 // USF vote enabled --> Set MAC mode to dynamic mode
1179 mac_mode = DYN_ALLOC;
1180 else
1181 // USF vote disabled --> Set MAC mode to fixed mode
1182 mac_mode = FIX_ALLOC_NO_HALF;
1183 #endif
1184
1185 #endif // !FF_L1_IT_DSP_USF
1186
1187 // MAC mode.
1188 l1ps_dsp_com.pdsp_ndb_ptr->d_sched_mode_gprs &= ~(3 << B_MAC_MODE);
1189 l1ps_dsp_com.pdsp_ndb_ptr->d_sched_mode_gprs |= mac_mode << B_MAC_MODE;
1190 }
1191
1192 #if FF_L1_IT_DSP_USF
1193 if(burst_nb == 3)
1194 {
1195 // Program DSP to generate an interrupt once USF available if
1196 // required. Latched by DSP during Work3.
1197 if (dsp_usf_interrupt)
1198 l1ps_dsp_com.pdsp_ndb_ptr->d_usf_vote_enable = (1 << B_USF_IT);
1199 else
1200 l1ps_dsp_com.pdsp_ndb_ptr->d_usf_vote_enable = 0;
1201 }
1202 #endif
1203
1204 // RIF receiver algorithm: select 156.25.
1205 l1ps_dsp_com.pdsp_ndb_ptr->d_sched_mode_gprs &= 0xFFFF ^ (1 << B_RIF_RX_MODE);
1206
1207 // d_fn
1208 // ----
1209 // bit [0..7] -> b_fn_report, unused for GPRS
1210 // bit [8..15] -> b_fn_sid , FN%104
1211 l1s_dsp_com.dsp_db_w_ptr->d_fn = ((l1s.next_time.fn_mod104)<<8);
1212
1213 // Training sequence.
1214 // Rem: bcch_freq_ind is set within Hopping algo.
1215 l1s_dsp_com.dsp_db_w_ptr->d_ctrl_system |= tsc << B_TSQ;
1216
1217 }
1218
1219
1220 /*-------------------------------------------------------*/
1221 /* l1pddsp_transfer_mslot_power() */
1222 /*-------------------------------------------------------*/
1223 /* Parameters : */
1224 /* Return : */
1225 /* Functionality : */
1226 /*-------------------------------------------------------*/
1227 void l1pddsp_transfer_mslot_power(UWORD8 *txpwr,
1228 UWORD16 radio_freq,
1229 UWORD8 ul_bitmap)
1230 {
1231 #define NO_TX 100
1232
1233 UWORD16 i; // 16 bit needed for shifting pupose.
1234 UWORD8 last_TX = NO_TX;
1235 UWORD8 txpwr_ramp_up;
1236 UWORD8 txpwr_ramp_down;
1237 UWORD8 cpt_TX = 0;
1238 UWORD8 ts_mask;
1239
1240 #if (REL99 && FF_PRF)
1241 UWORD8 number_uplink_timeslot = 0 ; // number of uplink timeslot for power reduction feature
1242 #endif
1243
1244
1245 #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3) || (RF_FAM == 61))
1246 UWORD16 pwr_data;
1247 UWORD16 d_ramp_idx;
1248 WORD16 ts_conv;
1249 #endif
1250
1251 //Locosto #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
1252
1253 // This function is called with an ul_bitmap which represents the abolute
1254 // position of any Tx bursts in this frame. This bitmap has already
1255 // absorbed any synchro change (in dl_tn), hence we need to do some
1256 // processing to recover the actual Tx timeslot number which is used
1257 // as an index into the txpwr array.
1258 //
1259 // Example : MS Class 8 with 4 Rx and 1 Tx :
1260 //
1261 //
1262 // dl_ts_alloc : 0x0f 0 0 0 0 R R R R
1263 // ul_ts_alloc : 0x02 0 0 0 0 0 0 T 0
1264 // shift + combine : 0 0 0 0 R R R R 0 T
1265 // set dl_tn=4 : R R R R 0 T 0 0
1266 // ul_bitmap : 0x04 0 0 0 0 0 1 0 0
1267 // i : 5
1268 //
1269 // Example : MS Class 8 with 1 Rx and 1 Tx on TS=7
1270 //
1271 // dl_ts_alloc : 0x01 0 0 0 0 0 0 0 R
1272 // ul_ts_alloc : 0x01 0 0 0 0 0 0 0 T
1273 // shift + combine : 0 0 0 0 0 0 0 R 0 0 T
1274 // set dl_tn=7 : R 0 0 T 0 0 0 0
1275 // ul_bitmap : 0x10 0 0 0 1 0 0 0 0
1276 // i : 3
1277 //
1278 // We recover the actual timeslot from the ul_bitmap by the following
1279 // method :
1280 //
1281 // ts = (i + dl_tn) - 3
1282 //
1283 // Where i is the loopindex usd to detect "1" in the ul_bitmap.
1284 // This works for MS class 8 because (3 <= i <= 5) if the
1285 // multislot class is respected.
1286
1287 #if (REL99 && FF_PRF)// power reduction feature
1288 for (i=0; i<8; i++)
1289 {
1290 // computed number of uplink timeslot in order to determine uplink power reduction
1291 ts_mask = (0x80>>i);
1292 if (ul_bitmap & ts_mask)
1293 number_uplink_timeslot++;
1294 }
1295 #endif
1296
1297
1298 ts_conv = l1a_l1s_com.dl_tn - 3;
1299
1300 // Index of the programmed ramps
1301 d_ramp_idx = 0;
1302
1303 for(i=0;i<8;i++)
1304 {
1305 // Program Transmit power and ramp for allocated timeslots.
1306 if(ul_bitmap & (0x80>>i))
1307 {
1308 // Fixe transmit power.
1309 if(l1_config.tx_pwr_code == 0)
1310 {
1311 // Store Transmit power.
1312 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_power_gprs[i] = l1_config.params.fixed_txpwr;
1313
1314 // Control bitmap: update RAMP, use RAMP[d_ramp_idx][..].
1315 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[i] =
1316 ((d_ramp_idx << B_RAMP_NB_GPRS) | (1 << B_RAMP_GPRS) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2));
1317
1318 // Store Ramp.
1319 #if (RF_FAM == 61)
1320 #if (DSP ==38) || (DSP == 39)
1321 Cust_get_ramp_tab(l1ps_dsp_com.pdsp_ndb_ptr->a_drp_ramp2_gprs[d_ramp_idx++],
1322 0, /* not used */
1323 0, /* not used */
1324 1 /* arbitrary value for arfcn */ );
1325 #endif
1326 #else
1327 #if (CODE_VERSION != SIMULATION)
1328 Cust_get_ramp_tab(l1ps_dsp_com.pdsp_ndb_ptr->a_ramp_gprs[d_ramp_idx++],
1329 0, /* not used */
1330 0, /* not used */
1331 1 /* arbitrary value for arfcn */ );
1332 #endif
1333 #endif
1334 }
1335 else
1336 {
1337 // count the number of TX windows
1338 cpt_TX ++;
1339
1340 // Get power amplifier data.
1341 #if(REL99 && FF_PRF)
1342 pwr_data = Cust_get_pwr_data(txpwr[i+ts_conv], radio_freq, number_uplink_timeslot);
1343 #else
1344 pwr_data = Cust_get_pwr_data(txpwr[i+ts_conv], radio_freq);
1345 #endif
1346
1347
1348 // Store Transmit power.
1349 #if(RF_FAM == 61)
1350 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_power_gprs[i] = (pwr_data);
1351 #else
1352 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_power_gprs[i] = ((pwr_data << 6) | 0x12);
1353 #endif
1354
1355 // Control bitmap: update RAMP, use RAMP[d_ramp_idx][..] for slot i.
1356 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[i] = ((d_ramp_idx << B_RAMP_NB_GPRS) | (1 << B_RAMP_GPRS) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2));
1357
1358 // Store Ramp.
1359 // ==========
1360 // for the 1st TX the RAMP is: RAMP_UP_TX1 / RAMP_DOWN_TX1
1361 // for the 2nd TX the RAMP is: RAMP_UP_TX2 / RAMP_DOWN_TX1
1362 // for the 3rd TX the RAMP is: RAMP_UP_TX3 / RAMP_DOWN_TX2
1363 // (...)
1364 // for the (i)th TX the RAMP is: RAMP_UP_TX_(i) / RAMP_DOWN_TX_(i-1)
1365 // for the additionnal RAMP : xxxx / RAMP_DOWN_TX_last
1366
1367 txpwr_ramp_up = txpwr[i+ts_conv]; // the ramp up is the current TX
1368
1369 if(last_TX == NO_TX) // specific case of the first TX
1370 txpwr_ramp_down = txpwr[i+ts_conv]; // the ramp down is the current TX
1371 else
1372 txpwr_ramp_down = txpwr[last_TX+ts_conv]; // the ramp down is the previous TX
1373
1374 #if(RF_FAM == 61)
1375 #if(DSP == 38) || (DSP == 39)
1376 Cust_get_ramp_tab(&(l1ps_dsp_com.pdsp_ndb_ptr->a_drp_ramp2_gprs[d_ramp_idx++][0]), txpwr_ramp_up, txpwr_ramp_down, radio_freq);
1377 #endif
1378 #else
1379 #if (CODE_VERSION != SIMULATION)
1380 Cust_get_ramp_tab(&(l1ps_dsp_com.pdsp_ndb_ptr->a_ramp_gprs[d_ramp_idx++][0]), txpwr_ramp_up, txpwr_ramp_down, radio_freq);
1381 #endif
1382 #endif
1383 }
1384
1385 // memorize the last TX window
1386 last_TX = i;
1387 }
1388 else
1389 {
1390 // program an interrupt in the TS following
1391 // the last TX window and needed by the DSP
1392
1393 // Is it the TS following a TX window ?
1394 #if 0 /* original LoCosto code */
1395 if((i == last_TX+1) && (i<8))
1396 #else /* FreeCalypso TCS211 reconstruction */
1397 if (i == last_TX+1)
1398 #endif
1399 {
1400 // program the interrupt
1401 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[i] = (1 << B_MS_RULE);
1402 }
1403 }
1404 }
1405
1406 // in a multi-TX case an additionnal ramp down must be set
1407 if(cpt_TX > 1)
1408 {
1409 // Control bitmap: update RAMP, use RAMP[d_ramp_idx][..] for slot i and set the interrupt
1410 #if 0 /* FreeCalypso TCS211 reconstruction */
1411 if((last_TX+1) <= 7)
1412 #endif
1413 l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[last_TX+1] = ((d_ramp_idx << B_RAMP_NB_GPRS) | (1 << B_RAMP_GPRS) | (1 << B_MS_RULE));
1414
1415 // Store Ramp.
1416 // ==========
1417 txpwr_ramp_up = txpwr[last_TX+ts_conv]; // this ramp up is unused (default: set to last_TX)
1418 txpwr_ramp_down = txpwr[last_TX+ts_conv]; // the ramp down is the last TX
1419
1420 #if(RF_FAM == 61)
1421 #if(DSP ==38) || (DSP == 39)
1422 Cust_get_ramp_tab(&(l1ps_dsp_com.pdsp_ndb_ptr->a_drp_ramp2_gprs[d_ramp_idx][0]), txpwr_ramp_up, txpwr_ramp_down, radio_freq);
1423 #endif
1424 #else
1425 #if (CODE_VERSION != SIMULATION)
1426 Cust_get_ramp_tab(&(l1ps_dsp_com.pdsp_ndb_ptr->a_ramp_gprs[d_ramp_idx][0]), txpwr_ramp_up, txpwr_ramp_down, radio_freq);
1427 #endif
1428 #endif
1429 }
1430 // #endif Locosto
1431 }
1432
1433
1434 /*-------------------------------------------------------*/
1435 /* l1pddsp_ul_ptcch_data() */
1436 /*-------------------------------------------------------*/
1437 /* Parameters : */
1438 /* Return : */
1439 /* Functionality : */
1440 /*-------------------------------------------------------*/
1441 void l1pddsp_ul_ptcch_data(UWORD8 cs_type,
1442 UWORD16 channel_request_data,
1443 UWORD8 bsic,
1444 UWORD16 radio_freq,
1445 UWORD8 timeslot_no)
1446 {
1447 UWORD16 swap_bit; // 16 bit wide to allow shift left.
1448
1449 // UL on TS=timeslot_no.
1450 l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= 0x80 >> timeslot_no;
1451
1452 // Swap I/Q management.
1453 swap_bit = l1ps_swap_iq_ul(radio_freq);
1454 l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= swap_bit << 15;
1455
1456 // Set "b_ptcch_ul" to indicate PTCCH/UL to DSP.
1457 l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= (1 << B_PTCCH_UL);
1458
1459 // Store CS type.
1460 l1ps_dsp_com.pdsp_ndb_ptr->a_ptcchu_gprs[0] = cs_type;
1461
1462 // Store UL data block.
1463 if(cs_type == CS_PAB8_TYPE)
1464 {
1465 l1ps_dsp_com.pdsp_ndb_ptr->a_ptcchu_gprs[1] = ((API)(bsic << 2)) |
1466 ((API)(channel_request_data) << 8);
1467 l1ps_dsp_com.pdsp_ndb_ptr->a_ptcchu_gprs[2] = 0;
1468 }
1469 else
1470 {
1471 l1ps_dsp_com.pdsp_ndb_ptr->a_ptcchu_gprs[1] = ((API)(channel_request_data) << 5);
1472 l1ps_dsp_com.pdsp_ndb_ptr->a_ptcchu_gprs[2] = ((API)(bsic << 10));
1473 }
1474 }
1475
1476
1477 /*-------------------------------------------------------*/
1478 /* l1pddsp_interf_meas_ctrl() */
1479 /*-------------------------------------------------------*/
1480 /* Parameters : */
1481 /* Return : */
1482 /* Functionality : */
1483 void l1pddsp_interf_meas_ctrl(UWORD8 nb_meas_req)
1484 {
1485 // Interference measurement task set as a monitoring task within GSM interface.
1486 // 101 means 1 meas, 102 means 2 meas ...
1487 // Rem: swap I/Q is not managed for power measurements.
1488 l1s_dsp_com.dsp_db_w_ptr->d_task_md = INTERF_DSP_TASK + nb_meas_req;
1489 }
1490
1491
1492 /*-------------------------------------------------------*/
1493 /* l1pddsp_transfer_meas_ctrl() */
1494 /*-------------------------------------------------------*/
1495 /* Parameters : */
1496 /* Return : */
1497 /* Functionality : */
1498 /*-------------------------------------------------------*/
1499 void l1pddsp_transfer_meas_ctrl(UWORD8 meas_position)
1500 {
1501 // Store measurement position.
1502 // Rem: This is a L1S filtered information giving the position of the meas. as a
1503 // bitmap.
1504 // Rem: swap I/Q is not managed for power measurements.
1505 l1ps_dsp_com.pdsp_db_w_ptr->d_task_pm_gprs = meas_position;
1506 }
1507
1508 /*-------------------------------------------------------*/
1509 /* l1pddsp_meas_ctrl() */
1510 /*-------------------------------------------------------*/
1511 /* Parameters : */
1512 /* Return : */
1513 /* Functionality : */
1514 /*-------------------------------------------------------*/
1515 void l1pddsp_meas_ctrl(UWORD8 nbmeas, UWORD8 pm_pos)
1516 {
1517 // Request Signal level measurement task to DSP. A bit map is passed
1518 // to DSP in order to specify the position of the measurement.
1519 // Note: MSB is TN = 0 and LSB is TN = 7.
1520 // Rem: swap I/Q is not managed for power measurements.
1521 // Note: currently a maximum of four Pm can be performed / TDMA. This would
1522 // be modified in a near futur.
1523 // Note: If a Rx is programmed i.e. pm_pos = 1, only a maximum
1524 // of 3 Pm is requested to DSP and position of the Pm are right shifted (Rx on TN = 0).
1525 // Remark: In packet Idle mode Rx are still on TN = 0. This implies three Pm
1526 // always after the Rx.
1527 l1ps_dsp_com.pdsp_db_w_ptr->d_task_pm_gprs = ((UWORD8) (0xff << (8 - nbmeas))) >> pm_pos;
1528 }
1529
1530 /*-------------------------------------------------------*/
1531 /* l1pddsp_meas_read() */
1532 /*-------------------------------------------------------*/
1533 /* Parameters : */
1534 /* Return : */
1535 /* Functionality : */
1536 /*-------------------------------------------------------*/
1537 void l1pddsp_meas_read(UWORD8 nbmeas, UWORD8 *a_pm)
1538 {
1539 UWORD8 i = 0;
1540 UWORD8 j;
1541 UWORD8 bit_mask = 0x80;
1542
1543 // Looks for first PM position
1544 while ((i < 8) && (l1ps_dsp_com.pdsp_db_r_ptr->d_task_pm_gprs & bit_mask) == 0)
1545 {
1546 i++;
1547 bit_mask >>= 1;
1548 }
1549
1550 // Read 'nbmeas' contiguous PM levels from the first PM position
1551 // Note: PM are always programmed on contiguous timeslots
1552 #if 0 /* original LoCosto code */
1553 for (j = 0; ((j < nbmeas)&&(i < 8)); j++)
1554 #else /* FreeCalypso TCS211 reconstruction */
1555 for (j = 0; j < nbmeas; j++)
1556 #endif
1557 {
1558 // Download PM from DSP/MCU memory interface
1559 a_pm[j] = (l1ps_dsp_com.pdsp_db_r_ptr->a_burst_pm_gprs[i] & 0xffff) >> 5;
1560
1561 // Read next PM on following TN
1562 i++;
1563 }
1564 }
1565
1566 /*-------------------------------------------------------*/
1567 /* l1pddsp_load_bcchn_task() */
1568 /*-------------------------------------------------------*/
1569 /* Parameters : */
1570 /* Return : */
1571 /* Functionality : */
1572 /*-------------------------------------------------------*/
1573 void l1pddsp_load_bcchn_task(UWORD8 tsq,UWORD16 radio_freq )
1574 {
1575 UWORD16 swap_bit = l1ps_swap_iq_dl(radio_freq);
1576
1577 l1s_dsp_com.dsp_db_w_ptr->d_task_md = NBN_DSP_TASK | (swap_bit << 15); // Load BCCHN task
1578 l1s_dsp_com.dsp_db_w_ptr->d_ctrl_system |= tsq << B_TSQ;
1579 }
1580 #endif