comparison src/cs/layer1/tm_cfile/l1tm_func.c @ 234:b870b6a44d31

l1audio and l1tm reconstructed source imported from tcs211-l1-reconst
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 20 Mar 2017 00:51:20 +0000
parents
children
comparison
equal deleted inserted replaced
233:17d79c62e638 234:b870b6a44d31
1 /************* Revision Controle System Header *************
2 * GSM Layer 1 software
3 * L1TM_FUNC.C
4 *
5 * Filename l1tm_func.c
6 * Copyright 2003 (C) Texas Instruments
7 *
8 ************* Revision Controle System Header *************/
9
10 #include "l1_macro.h"
11 #include "l1_confg.h"
12
13 #if TESTMODE
14 #define L1TM_FUNC_C
15
16 #include <string.h>
17 #include <math.h>
18 #include "abb.h"
19
20 #include "general.h"
21
22 #include "l1_types.h"
23 #include "sys_types.h"
24 #include "l1_const.h"
25 #include "l1_time.h"
26 #include "l1_signa.h"
27
28 #include "l1tm_defty.h"
29
30 #if 0 //(CODE_VERSION != SIMULATION) // LoCosto-ism
31 #include "pld.h"
32 #endif
33
34 #if (TRACE_TYPE==1) || (TRACE_TYPE==4) || (TRACE_TYPE==7) || (TRACE_TYPE==0)
35 #include "rvt_gen.h"
36 extern T_RVT_USER_ID tm_trace_user_id;
37 #endif
38
39 #if (AUDIO_TASK == 1)
40 #include "l1audio_const.h"
41 #include "l1audio_cust.h"
42 #include "l1audio_defty.h"
43 #endif
44
45 #if (L1_GTT == 1)
46 #include "l1gtt_const.h"
47 #include "l1gtt_defty.h"
48 #endif
49
50 #if (L1_MP3 == 1)
51 #include "l1mp3_defty.h"
52 #endif
53
54 #if (L1_MIDI == 1)
55 #include "l1midi_defty.h"
56 #endif
57
58 #include "l1_defty.h"
59 #include "cust_os.h"
60 #include "l1_msgty.h"
61 #include "l1_varex.h"
62 #include "l1_proto.h"
63
64 #include "mem.h"
65
66 #if (CODE_VERSION != SIMULATION)
67
68 #if (RF_FAM == 61)
69 #include "tpudrv61.h"
70 #include "l1_rf61.h"
71 #include "l1tm_tpu61.h"
72 #if (DRP_FW_EXT==1)
73 #include "l1_drp_inc.h"
74 #else
75 #include "drp_drive.h"
76 #endif
77 #endif
78
79 #if (RF_FAM == 60)
80 #include "tpudrv60.h"
81 #include "l1_rf60.h"
82 #include "l1tm_tpu60.h"
83 #include "drp_drive.h"
84 #endif
85
86 #if (RF_FAM==43)
87 #include "tpudrv43.h"
88 #include "l1_rf43.h"
89 #include "l1tm_tpu43.h"
90 #endif
91 #if (RF_FAM == 35)
92 #include "tpudrv35.h"
93 #include "l1_rf35.h"
94 #include "l1tm_tpu35.h"
95 #endif
96
97 #if (RF_FAM == 12)
98 #include "tpudrv12.h"
99 #include "l1_rf12.h"
100 #include "l1tm_tpu12.h"
101 #endif
102
103 #if (RF_FAM == 10)
104 #include "tpudrv10.h"
105 #include "l1_rf10.h"
106 #include "l1tm_tpu10.h"
107 #endif
108
109 #if (RF_FAM == 8)
110 #include "tpudrv8.h"
111 #include "l1_rf8.h"
112 #include "l1tm_tpu8.h"
113 #endif
114
115 #if (RF_FAM == 2)
116 #include "tpudrv2.h"
117 #include "l1_rf2.h"
118 #include "l1tm_tpu2.h"
119 #endif
120
121 #else
122
123 #if (RF_FAM == 2)
124 #include "l1_rf2.h"
125 #endif
126
127 #endif
128
129 #include <assert.h>
130 #include <string.h>
131
132 #include "l1tm_msgty.h"
133 #include "l1tm_signa.h"
134 #include "l1tm_varex.h"
135 #include "l1tm_ver.h"
136
137 #if L1_GPRS
138 #include "l1p_cons.h"
139 #include "l1p_msgt.h"
140 #include "l1p_deft.h"
141 #include "l1p_vare.h"
142 #include "l1p_sign.h"
143 #endif
144
145 #if ((L1_STEREOPATH == 1) && (OP_L1_STANDALONE == 1))
146 #include "sys_dma.h"
147 #endif
148
149 #if(L1_FF_MULTIBAND == 1)
150 extern UWORD8 tm_band;
151 #endif /*if (L1_FF_MULTIBAND == 1)*/
152
153
154 // Prototypes from external functions
155 //------------------------------------
156 UWORD16 Convert_l1_radio_freq(SYS_UWORD16 radio_freq);
157
158 void Cust_tm_rf_param_write (T_TM_RETURN *tm_return, WORD16 index, UWORD16 value);
159 void Cust_tm_rf_param_read (T_TM_RETURN *tm_return, WORD16 index);
160 void Cust_tm_rf_table_write (T_TM_RETURN *tm_return, WORD8 index, UWORD8 size, UWORD8 table[]);
161 void Cust_tm_rf_table_read (T_TM_RETURN *tm_return, WORD8 index);
162 void Cust_tm_rx_param_write (T_TM_RETURN *tm_return, WORD16 index, UWORD16 value);
163 void Cust_tm_rx_param_read (T_TM_RETURN *tm_return, WORD16 index);
164 void Cust_tm_tx_param_write (T_TM_RETURN *tm_return, WORD16 index, UWORD16 value, UWORD8 band);
165 void Cust_tm_tx_param_read (T_TM_RETURN *tm_return, WORD16 index, UWORD8 band);
166 void Cust_tm_tx_template_write (T_TM_RETURN *tm_return, WORD8 index, UWORD8 size, UWORD8 table[]);
167 void Cust_tm_tx_template_read (T_TM_RETURN *tm_return, WORD8 index);
168 void Cust_tm_special_param_write (T_TM_RETURN *tm_return, WORD16 index, UWORD16 value);
169 void Cust_tm_special_param_read (T_TM_RETURN *tm_return, WORD16 index);
170 void Cust_tm_special_table_write (T_TM_RETURN *tm_return, WORD8 index, UWORD8 size, UWORD8 table[]);
171 void Cust_tm_special_table_read (T_TM_RETURN *tm_return, WORD8 index);
172 void Cust_tm_special_enable (T_TM_RETURN *tm_return, WORD16 action);
173
174 #if (CODE_VERSION != SIMULATION)
175 void Cust_tm_tpu_table_write (T_TM_RETURN *tm_return, WORD8 index, UWORD8 size, UWORD8 table[]);
176 void Cust_tm_tpu_table_read (T_TM_RETURN *tm_return, WORD8 index);
177 #endif
178
179 //------------------------------------
180 // Prototypes from external functions
181 //------------------------------------
182
183 void Cust_tm_init (void);
184 void l1tm_reset_rx_state (void);
185 void l1tm_reset_rx_stats (void);
186
187 #if L1_GPRS
188 void l1pa_reset_cr_freq_list (void);
189 #endif
190
191 //------------------------------------
192 // Prototypes from internal functions
193 //------------------------------------
194
195 void l1tm_initialize_var(void);
196 UWORD16 l1tm_convert_arfcn2l1ch(UWORD16 arfcn, UWORD8 *error_flag);
197 void l1tm_stats_read(T_TM_RETURN *tm_return, WORD16 type, UWORD16 bitmask);
198 void tm_transmit(T_TM_RETURN *tm_ret);
199 void l1tm_PRBS1_generate(UWORD16 *TM_ul_data);
200
201 #if ((L1_STEREOPATH == 1) && (OP_L1_STANDALONE == 1))
202 void l1tm_stereopath_DMA_handler(SYS_UWORD16 dma_status);
203 void l1tm_stereopath_fill_buffer(void* buffer_address);
204 UWORD16 l1tm_stereopath_get_pattern(UWORD16 sampling_freq, UWORD16 sin_freq_left,UWORD16 sin_freq_right, UWORD8 data_type);
205 #endif
206
207 /***********************************************************************/
208 /* TESTMODE 3.X */
209 /***********************************************************************/
210
211 static UWORD8 tx_param_band=0; // used in tx_param_write/read; default is GSM900
212
213
214
215
216 // RF,(ANALOG)or other hardware dependent functions
217 // - work done by tmrf.c functions for each product.
218
219 // TestMode functions that modify the state variables
220 // within the L1A - may need to allocate space
221 // dynamically if this is the first time calling
222 // these functions.
223
224 // TestMode functions that start L1A state machines
225 // may need to send L1A primitives to change L1A state.
226
227 void l1tm_rf_param_write(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
228 {
229 tm_return->index = prim->u.tm_params.index;
230 tm_return->size = 0;
231
232 switch (prim->u.tm_params.index)
233 {
234 #if (FF_REPEATED_SACCH == 1)
235 // Repeated SACCH mode
236 case REPEATED_SACCH_ENA_FLAG:
237 {
238 l1_config.repeat_sacch_enable = prim->u.tm_params.value;
239 #if (ETM_PROTOCOL == 1)
240 tm_return->status = -ETM_OK;
241 #else
242 tm_return->status = E_OK;
243 #endif
244 break;
245 }
246 #endif /* FF_REPEATED_SACCH */
247
248 #if (FF_REPEATED_DL_FACCH == 1)
249 // Repeated FACCH mode
250 case REPEATED_FACCHDL_ENA_FLAG:
251 {
252 l1_config.repeat_facch_dl_enable = prim->u.tm_params.value;
253 #if (ETM_PROTOCOL == 1)
254 tm_return->status = -ETM_OK;
255 #else
256 tm_return->status = E_OK;
257 #endif/*(ETM_PROTOCOL == 1)*/
258
259 break;
260 }
261 #endif /* FF_REPEATED_DL_FACCH == 1 */
262 case BCCH_ARFCN:
263 {
264 UWORD16 bcch_arfcn;
265 UWORD8 error_flag;
266
267 bcch_arfcn = l1tm_convert_arfcn2l1ch(prim->u.tm_params.value, &error_flag);
268
269 if (error_flag)
270 {
271 #if (ETM_PROTOCOL == 1)
272 tm_return->status = -ETM_INVAL;
273 #else
274 tm_return->status = E_INVAL;
275 #endif
276 }
277 else
278 {
279 l1_config.tmode.rf_params.bcch_arfcn = bcch_arfcn;
280
281 // now change on the fly
282 // no reason to check dedicated_active flag...
283 // we just set these 2 globals for FB/SB/BCCH tests
284 l1a_l1s_com.nsync.list[0].radio_freq = l1_config.tmode.rf_params.bcch_arfcn;
285 l1a_l1s_com.Scell_info.radio_freq = l1_config.tmode.rf_params.bcch_arfcn;
286 #if (ETM_PROTOCOL == 1)
287 tm_return->status = -ETM_OK;
288 #else
289 tm_return->status = E_OK;
290 #endif
291 }
292 break;
293 }
294 case TCH_ARFCN:
295 {
296 T_CHN_SEL *chan_sel;
297 UWORD16 tch_arfcn;
298 UWORD8 error_flag;
299
300 tch_arfcn = l1tm_convert_arfcn2l1ch(prim->u.tm_params.value, &error_flag);
301
302 if (error_flag)
303 #if (ETM_PROTOCOL == 1)
304 tm_return->status = -ETM_INVAL;
305 #else
306 tm_return->status = E_INVAL;
307 #endif
308 else
309 {
310 l1_config.tmode.rf_params.tch_arfcn = tch_arfcn;
311
312 // now change on the fly if necessary
313 if (l1_config.TestMode && l1tm.tmode_state.dedicated_active)
314 {
315 chan_sel = &(l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->chan_sel);
316 chan_sel->rf_channel.single_rf.radio_freq = l1_config.tmode.rf_params.tch_arfcn;
317 }
318 #if (ETM_PROTOCOL == 1)
319 tm_return->status = -ETM_OK;
320 #else
321 tm_return->status = E_OK;
322 #endif
323 }
324 break;
325 }
326 case MON_ARFCN:
327 {
328 UWORD16 mon_arfcn;
329 UWORD8 error_flag;
330
331 mon_arfcn = l1tm_convert_arfcn2l1ch(prim->u.tm_params.value, &error_flag);
332
333 if (error_flag)
334 #if (ETM_PROTOCOL == 1)
335 tm_return->status = -ETM_INVAL;
336 #else
337 tm_return->status = E_INVAL;
338 #endif
339 else
340 {
341 l1_config.tmode.rf_params.mon_arfcn = mon_arfcn;
342 #if (ETM_PROTOCOL == 1)
343 tm_return->status = -ETM_OK;
344 #else
345 tm_return->status = E_OK;
346 #endif
347 }
348 break;
349 }
350 #if L1_GPRS
351 case PDTCH_ARFCN:
352 {
353 UWORD16 pdtch_arfcn;
354 UWORD8 error_flag;
355
356 pdtch_arfcn = l1tm_convert_arfcn2l1ch(prim->u.tm_params.value, &error_flag);
357
358 if (error_flag)
359 #if (ETM_PROTOCOL == 1)
360 tm_return->status = -ETM_INVAL;
361 #else
362 tm_return->status = E_INVAL;
363 #endif
364 else
365 {
366 l1_config.tmode.rf_params.pdtch_arfcn = pdtch_arfcn;
367 #if (ETM_PROTOCOL == 1)
368 tm_return->status = -ETM_OK;
369 #else
370 tm_return->status = E_OK;
371 #endif
372 }
373 break;
374 }
375 #endif
376 case AFC_ENA_FLAG:
377 {
378 l1_config.afc_enable = prim->u.tm_params.value;
379 #if (ETM_PROTOCOL == 1)
380 tm_return->status = -ETM_OK;
381 #else
382 tm_return->status = E_OK;
383 #endif
384 break;
385 }
386 case AFC_DAC_VALUE:
387 {
388 WORD16 afc_value = prim->u.tm_params.value;
389 // 13-bit AFC DAC
390 #if(RF_FAM != 61)
391 if (afc_value<-4096 || afc_value>4095)
392 #else
393 if (afc_value<-8192 || afc_value>8191)
394 #endif
395 {
396 #if (ETM_PROTOCOL == 1)
397 tm_return->status = -ETM_INVAL;
398 #else
399 tm_return->status = E_INVAL;
400 #endif
401 break;
402 }
403
404 if (!l1_config.afc_enable)
405 {
406 // write AFC value to AFC DAC ASAP!! AFC DAC will be updated by any RX
407 // or TX test.
408 l1s.afc = afc_value;
409 }
410
411 #if (ETM_PROTOCOL == 1)
412 tm_return->status = -ETM_OK;
413 #else
414 tm_return->status = E_OK;
415 #endif
416 break;
417 }
418 #if L1_GPRS
419 case MULTISLOT_CLASS:
420 {
421 UWORD8 multislot_class;
422
423 multislot_class = prim->u.tm_params.value;
424
425 if ((multislot_class < 1) || (multislot_class > 12))
426 #if (ETM_PROTOCOL == 1)
427 tm_return->status = -ETM_INVAL;
428 #else
429 tm_return->status = E_INVAL;
430 #endif
431 else
432 {
433 l1_config.tmode.rf_params.multislot_class = multislot_class;
434 #if (ETM_PROTOCOL == 1)
435 tm_return->status = -ETM_OK;
436 #else
437 tm_return->status = E_OK;
438 #endif
439 }
440 break;
441 }
442 #endif // end of L1_GPRS
443 default:
444 {
445 Cust_tm_rf_param_write(tm_return,
446 prim->u.tm_params.index,
447 prim->u.tm_params.value);
448 break;
449 }
450 } // end switch
451 }
452
453 UWORD16 l1tm_convert_arfcn2l1ch(UWORD16 arfcn, UWORD8 *error_flag)
454 #if (L1_FF_MULTIBAND == 0)
455 {
456 /* Here, before we store the channel numbers to the l1_config structure,
457 we convert from ETSI to TI channel numbering system. The GGT
458 ALWAYS expects the ETSI numbering system as input and output.
459
460 We need to do the OPPOSITE of what is done in convert_l1_arfcn() in
461 tpudrvX.c
462
463 ***************************************
464 *** convert arfcn's from ETSI to TI ***
465 ***************************************
466 ** **
467 ** ETSI TI **
468 ** 0 GSM 174 **
469 ** 1 - 124 GSM 1 - 124 **
470 ** 975 - 1023 E-GSM 125 - 173 **
471 ** 512 - 885 DCS 174 - 548 **
472 ** **
473 *************************************** */
474
475 *error_flag = 0;
476
477 switch (l1_config.std.id)
478 {
479 case GSM:
480 case DCS1800:
481 case PCS1900:
482 case GSM850:
483 break;
484
485 case DUAL:
486 if ((arfcn >= 512) && (arfcn <= 885)) arfcn -= 337;
487 else if (arfcn > 124) *error_flag = 1; // invalid arfcn
488 break;
489
490 case DUALEXT:
491 if (arfcn == 0) arfcn = 174;
492 else if ((arfcn >= 975) && (arfcn <= 1023)) arfcn -= 850;
493 else if ((arfcn >= 512) && (arfcn <= 885)) arfcn -= 337;
494 else if ((arfcn >= 1) && (arfcn <= 124));
495 else *error_flag = 1; // invalide arfcn
496 break;
497
498 case DUAL_US: // GSM850:128-251 PCS1900:512-810
499 if ((arfcn >= 128) && (arfcn <= 251)) arfcn -= 127;
500 else if ((arfcn >= 512) && (arfcn <= 810)) arfcn -= 387;
501 else *error_flag = 1; // invalid arfcn
502 break;
503
504 default:
505 *error_flag = 1; // invalid std.id
506 break;
507 } // end switch
508 return arfcn;
509 }
510 #else // L1_FF_MULTIBAND = 1 below
511
512 {
513 *error_flag=0;
514 if(tm_band == RF_PCS1900)
515 {
516 arfcn = arfcn + 512;
517 }
518 return(arfcn);
519 #if 0
520 UWORD16 l1_radio_freq = 0;
521 UWORD8 effective_band_id = 0;
522 *error_flag = 1;
523 for (effective_band_id = 0; effective_band_id < RF_NB_SUBBANDS; effective_band_id ++)
524 {
525 if( multiband_conversion_data[effective_band_id].physical_band_id == tm_band)
526 {
527 if( (arfcn - multiband_conversion_data[effective_band_id].first_tpu_radio_freq) < multiband_conversion_data[effective_band_id].nbmax_carrier)
528 {
529 l1_radio_freq = arfcn - multiband_conversion_data[effective_band_id].first_tpu_radio_freq + multiband_conversion_data[effective_band_id].first_radio_freq;
530 *error_flag = 0;
531 return(l1_radio_freq);
532 }
533 }
534 }
535 return(l1_radio_freq);
536 #endif
537
538 }
539
540 #endif // #if (L1_FF_MULTIBAND == 0) else
541
542
543 void l1tm_rf_param_read(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
544 {
545 volatile UWORD16 value;
546
547 tm_return->index = prim->u.tm_params.index;
548
549 switch (prim->u.tm_params.index)
550 {
551 #if (FF_REPEATED_SACCH == 1 )
552 /* Repeated SACCH mode */
553 case REPEATED_SACCH_ENA_FLAG:
554 {
555 value = l1_config.repeat_sacch_enable;
556 break;
557 }
558 #endif /* FF_REPEATED_SACCH */
559
560 #if FF_REPEATED_DL_FACCH
561 // Repeated FACCH mode
562 case REPEATED_FACCHDL_ENA_FLAG:
563 {
564 value = l1_config.repeat_facch_dl_enable;
565 break;
566 }
567 #endif /* FF_REPEATED_DL_FACCH */
568
569
570 case BCCH_ARFCN:
571 {
572 // return ETSI value for channel number
573 value = Convert_l1_radio_freq(l1_config.tmode.rf_params.bcch_arfcn);
574 break;
575 }
576 case TCH_ARFCN:
577 {
578 // return ETSI value for channel number
579 value = Convert_l1_radio_freq(l1_config.tmode.rf_params.tch_arfcn);
580 break;
581 }
582 case MON_ARFCN:
583 {
584 // return ETSI value for channel number
585 value = Convert_l1_radio_freq(l1_config.tmode.rf_params.mon_arfcn);
586 break;
587 }
588 #if L1_GPRS
589 case PDTCH_ARFCN:
590 {
591 // return ETSI value for channel number
592 value = Convert_l1_radio_freq(l1_config.tmode.rf_params.pdtch_arfcn);
593 break;
594 }
595 #endif
596 case AFC_ENA_FLAG:
597 {
598 value = l1_config.afc_enable;
599 break;
600 }
601 case AFC_DAC_VALUE:
602 {
603 value = l1s.afc; // returned as F13.3
604 break;
605 }
606 #if L1_GPRS
607 case MULTISLOT_CLASS:
608 {
609 value = l1_config.tmode.rf_params.multislot_class;
610 break;
611 }
612 #endif
613 default:
614 {
615 Cust_tm_rf_param_read(tm_return, prim->u.tm_params.index);
616 return;
617 }
618 } // end switch
619
620 memcpy(tm_return->result, (UWORD8 *)&value, 2);
621 tm_return->size = 2;
622 #if (ETM_PROTOCOL == 1)
623 tm_return->status = -ETM_OK;
624 #else
625 tm_return->status = E_OK;
626 #endif
627 }
628
629 void l1tm_rf_table_write(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
630 {
631 Cust_tm_rf_table_write(tm_return,
632 prim->u.tm_table.index,
633 prim->str_len_in_bytes - 1, // subtract 8-bit index
634 prim->u.tm_table.table);
635 }
636
637 void l1tm_rf_table_read(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
638 {
639 Cust_tm_rf_table_read(tm_return, prim->u.tm_table.index);
640 }
641
642 void l1tm_rx_param_write(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
643 {
644 tm_return->index = prim->u.tm_params.index;
645 tm_return->size = 0;
646
647 switch (prim->u.tm_params.index)
648 {
649 case RX_AGC_GAIN:
650 {
651 WORD8 gain = prim->u.tm_params.value;
652
653 // It is up to the user to write a valid gain,
654 // one that falls within the range of gains in the current RF
655 // AGC gain can only be controlled in 2dB steps as the bottom bit (bit zero)
656 // corresponds to the lna_off bit
657 l1_config.tmode.rx_params.agc = gain & ~0x01;
658 l1_config.tmode.rx_params.lna_off = gain & 0x01;
659 #if (ETM_PROTOCOL == 1)
660 tm_return->status = -ETM_OK;
661 #else
662 tm_return->status = E_OK;
663 #endif
664 break;
665 }
666 case RX_TIMESLOT:
667 {
668 if (prim->u.tm_params.value > 7)
669 {
670 #if (ETM_PROTOCOL == 1)
671 tm_return->status = -ETM_INVAL;
672 #else
673 tm_return->status = E_INVAL;
674 #endif
675 break;
676 }
677
678 l1_config.tmode.rx_params.slot_num = prim->u.tm_params.value;
679 if (l1_config.TestMode && l1tm.tmode_state.dedicated_active)
680 {
681 // currently CANNOT change RX slot on the fly!
682 }
683
684 #if (ETM_PROTOCOL == 1)
685 tm_return->status = -ETM_OK;
686 #else
687 tm_return->status = E_OK;
688 #endif
689 break;
690 }
691 case RX_PM_ENABLE:
692 {
693 l1_config.tmode.rx_params.pm_enable = prim->u.tm_params.value;
694
695 #if (ETM_PROTOCOL == 1)
696 tm_return->status = -ETM_OK;
697 #else
698 tm_return->status = E_OK;
699 #endif
700 break;
701 }
702 #if L1_GPRS
703 case RX_GPRS_SLOTS:
704 {
705 // At least one DL TS needs to be allocated
706 if (!prim->u.tm_params.value)
707 #if (ETM_PROTOCOL == 1)
708 tm_return->status = -ETM_INVAL;
709 #else
710 tm_return->status = E_INVAL;
711 #endif
712 else
713 {
714 l1_config.tmode.rx_params.timeslot_alloc = prim->u.tm_params.value;
715 #if (ETM_PROTOCOL == 1)
716 tm_return->status = -ETM_OK;
717 #else
718 tm_return->status = E_OK;
719 #endif
720 }
721 break;
722 }
723 case RX_GPRS_CODING:
724 {
725 UWORD8 coding_scheme;
726
727 coding_scheme = prim->u.tm_params.value;
728 if ((coding_scheme < 1) || (coding_scheme > 6) || (coding_scheme == 3))
729 #if (ETM_PROTOCOL == 1)
730 tm_return->status = -ETM_INVAL;
731 #else
732 tm_return->status = E_INVAL;
733 #endif
734 else
735 {
736 l1_config.tmode.rx_params.coding_scheme = prim->u.tm_params.value;
737 #if (ETM_PROTOCOL == 1)
738 tm_return->status = -ETM_OK;
739 #else
740 tm_return->status = E_OK;
741 #endif
742 }
743 break;
744 }
745 #endif
746 case RX_AGC_ENA_FLAG:
747 {
748 l1_config.agc_enable = prim->u.tm_params.value;
749 #if (ETM_PROTOCOL == 1)
750 tm_return->status = -ETM_OK;
751 #else
752 tm_return->status = E_OK;
753 #endif
754 break;
755 }
756 default:
757 {
758 Cust_tm_rx_param_write(tm_return,
759 prim->u.tm_params.index,
760 prim->u.tm_params.value);
761 break;
762 }
763 } // end switch
764 }
765
766 void l1tm_rx_param_read(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
767 {
768 volatile UWORD16 value;
769
770 tm_return->index = prim->u.tm_params.index;
771
772 switch (prim->u.tm_params.index)
773 {
774 case RX_AGC_GAIN:
775 {
776 value = l1_config.tmode.rx_params.agc | l1_config.tmode.rx_params.lna_off;
777 break;
778 }
779 case RX_TIMESLOT:
780 {
781 value = l1_config.tmode.rx_params.slot_num;
782 break;
783 }
784 case RX_AGC_ENA_FLAG:
785 {
786 value = l1_config.agc_enable;
787 break;
788 }
789 case RX_PM_ENABLE:
790 {
791 value = l1_config.tmode.rx_params.pm_enable;
792 break;
793 }
794 #if L1_GPRS
795 case RX_GPRS_SLOTS:
796 {
797 value = l1_config.tmode.rx_params.timeslot_alloc;
798 break;
799 }
800 case RX_GPRS_CODING:
801 {
802 value = l1_config.tmode.rx_params.coding_scheme;
803 break;
804 }
805 #endif
806 default:
807 {
808 Cust_tm_rx_param_read(tm_return, prim->u.tm_params.index);
809 return;
810 }
811 } // end switch
812
813 memcpy(tm_return->result, (UWORD8 *)&value, 2);
814 tm_return->size = 2;
815 #if (ETM_PROTOCOL == 1)
816 tm_return->status = -ETM_OK;
817 #else
818 tm_return->status = E_OK;
819 #endif
820 }
821
822 void l1tm_tx_param_write(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
823 {
824 tm_return->index = prim->u.tm_params.index;
825 tm_return->size = 0;
826
827 switch (prim->u.tm_params.index)
828 {
829 case TX_PWR_LEVEL:
830 {
831 UWORD8 temp_txpwr, temp_band;
832
833 if (prim->u.tm_params.value < 100) // GSM900
834 {
835 temp_txpwr = prim->u.tm_params.value;
836 temp_band = 0;
837 }
838 else if (prim->u.tm_params.value < 200) // DCS1800
839 {
840 temp_txpwr = prim->u.tm_params.value - 100;
841 temp_band = 1;
842 }
843 else if (prim->u.tm_params.value < 300) // PCS1900
844 {
845 temp_txpwr = prim->u.tm_params.value - 200;
846 temp_band = 2;
847 }
848 else // force invalid values to return -ETM_INVAL or E_INVAL
849 {
850 temp_txpwr = 50;
851 temp_band = 10;
852 }
853
854 // Note that the pwr level is only checked for being within the range [0..31]
855 // because all pwr levels should be testable.
856 // For subfunctions [TX_APC_DAC..TX_DELAY_DOWN]:
857 // temp_txpwr + 0 ==> GSM900
858 // temp_txpwr + 100 ==> DCS1800
859 // temp_txpwr + 200 ==> PCS1900
860
861 // Changing tx pwr level on the fly while in continuous mode is not supported.
862 if (temp_txpwr > 31 || temp_band > 2 ||
863 l1_config.tmode.rf_params.tmode_continuous == TM_CONTINUOUS)
864 {
865 #if (ETM_PROTOCOL == 1)
866 tm_return->status = -ETM_INVAL;
867 #else
868 tm_return->status = E_INVAL;
869 #endif
870 break;
871 }
872
873 l1_config.tmode.tx_params.txpwr = temp_txpwr;
874 tx_param_band = temp_band;
875
876 // if in TX mode, change txpwr on the fly
877 if ((l1_config.TestMode) &&
878 (l1tm.tmode_state.dedicated_active) &&
879 (l1_config.tmode.rf_params.down_up & TMODE_UPLINK))
880 {
881 // this causes 'direct' changing of TXPWR, which is OK in TestMode
882 l1a_l1s_com.dedic_set.aset->new_target_txpwr = l1s.applied_txpwr = l1_config.tmode.tx_params.txpwr;
883 }
884
885 #if (ETM_PROTOCOL == 1)
886 tm_return->status = -ETM_OK;
887 #else
888 tm_return->status = E_OK;
889 #endif
890 break;
891 }
892 case TX_TIMING_ADVANCE:
893 {
894 l1_config.tmode.tx_params.timing_advance = prim->u.tm_params.value;
895
896 if (l1_config.TestMode && l1tm.tmode_state.dedicated_active)
897 {
898 // direct changing of Timing Advance
899 l1a_l1s_com.dedic_set.aset->new_timing_advance = l1_config.tmode.tx_params.timing_advance;
900 // new TA to take effect immediately
901 l1a_l1s_com.dedic_set.aset->timing_advance = l1a_l1s_com.dedic_set.aset->new_timing_advance;
902 }
903 #if (ETM_PROTOCOL == 1)
904 tm_return->status = -ETM_OK;
905 #else
906 tm_return->status = E_OK;
907 #endif
908 break;
909 }
910 case TX_PWR_SKIP:
911 {
912 l1_config.tmode.tx_params.txpwr_skip = prim->u.tm_params.value;
913 #if (ETM_PROTOCOL == 1)
914 tm_return->status = -ETM_OK;
915 #else
916 tm_return->status = E_OK;
917 #endif
918 break;
919 }
920 #if L1_GPRS
921 case TX_GPRS_POWER0:
922 case TX_GPRS_POWER1:
923 case TX_GPRS_POWER2:
924 case TX_GPRS_POWER3:
925 case TX_GPRS_POWER4:
926 case TX_GPRS_POWER5:
927 case TX_GPRS_POWER6:
928 case TX_GPRS_POWER7:
929 {
930 l1_config.tmode.tx_params.txpwr_gprs[prim->u.tm_params.index - TX_GPRS_POWER0] = prim->u.tm_params.value;
931 #if (ETM_PROTOCOL == 1)
932 tm_return->status = -ETM_OK;
933 #else
934 tm_return->status = E_OK;
935 #endif
936 break;
937 }
938 case TX_GPRS_SLOTS:
939 {
940 l1_config.tmode.tx_params.timeslot_alloc = prim->u.tm_params.value;
941 #if (ETM_PROTOCOL == 1)
942 tm_return->status = -ETM_OK;
943 #else
944 tm_return->status = E_OK;
945 #endif
946 break;
947 }
948 case TX_GPRS_CODING:
949 {
950 UWORD8 coding_scheme;
951
952 coding_scheme = prim->u.tm_params.value;
953 if ((coding_scheme < 2) || (coding_scheme > 6) || (coding_scheme == 3))
954 #if (ETM_PROTOCOL == 1)
955 tm_return->status = -ETM_INVAL;
956 #else
957 tm_return->status = E_INVAL;
958 #endif
959 else
960 {
961 l1_config.tmode.tx_params.coding_scheme = prim->u.tm_params.value;
962 #if (ETM_PROTOCOL == 1)
963 tm_return->status = -ETM_OK;
964 #else
965 tm_return->status = E_OK;
966 #endif
967 }
968 break;
969 }
970 #endif
971 default:
972 {
973 Cust_tm_tx_param_write(tm_return,
974 prim->u.tm_params.index,
975 prim->u.tm_params.value,
976 tx_param_band);
977 break;
978 }
979 } // end switch
980 }
981
982 void l1tm_tx_param_read(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
983 {
984 tm_return->index = prim->u.tm_params.index;
985
986 Cust_tm_tx_param_read(tm_return,
987 prim->u.tm_params.index,
988 tx_param_band);
989 }
990
991 void l1tm_tx_template_write(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
992 {
993 Cust_tm_tx_template_write(tm_return,
994 prim->u.tm_table.index,
995 prim->str_len_in_bytes - 1, // subtract 8-bit index
996 prim->u.tm_table.table);
997 }
998
999 void l1tm_tx_template_read(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1000 {
1001 Cust_tm_tx_template_read(tm_return, prim->u.tm_table.index);
1002 }
1003
1004 /* TCS211 function missing in LoCosto, reconstructed from disassembly */
1005 void l1tm_mode_set(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1006 {
1007 switch (prim->u.tm_params.index) {
1008 case 0:
1009 l1_config.TestMode = 0;
1010 tm_return->status = E_OK;
1011 break;
1012 case 1:
1013 l1_config.TestMode = 1;
1014 l1_config.tx_pwr_code = 1;
1015 l1_config.pwr_mngt = 0;
1016 tm_return->status = E_OK;
1017 Cust_tm_init();
1018 l1tm_initialize_var();
1019 break;
1020 default:
1021 tm_return->status = E_INVAL;
1022 }
1023 tm_return->index = 0;
1024 tm_return->size = 0;
1025 }
1026
1027 /* TCS211 function missing in LoCosto, reconstructed from disassembly */
1028 void l1tm_version_get(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1029 {
1030 UWORD16 revision;
1031 extern T_RF rf;
1032
1033 tm_return->index = prim->u.tm_params.index;
1034
1035 switch (prim->u.tm_params.index) {
1036 /* "meat" of this switch statement taken from LoCosto etm_tm3core.c */
1037 case BBCHIP_MODULE_REV:
1038 revision = CHIPSET;
1039 break;
1040 case CHIPID_MODULE_REV:
1041 revision = *( (volatile UWORD16 *) (MEM_JTAGID_PART));
1042 break;
1043 case CHIPVER_MODULE_REV:
1044 revision = *( (volatile UWORD16 *) (MEM_JTAGID_VER));
1045 break;
1046 case DSPSW_MODULE_REV:
1047 revision = l1s.version.dsp_code_version;
1048 break;
1049 case ANALOGCHIP_MODULE_REV:
1050 revision = ((ANLG_PG << 7) | ANLG_FAM);
1051 break;
1052 case LAYER1_MODULE_REV:
1053 revision = l1s.version.mcu_tcs_official;
1054 break;
1055 case RFDRIVER_MODULE_REV:
1056 revision = rf.rf_revision;
1057 break;
1058 case TM_API_MODULE_REV:
1059 revision = TMAPIVERSION;
1060 break;
1061 case L1_TM_CORE_MODULE_REV:
1062 revision = l1s.version.mcu_tm_version;
1063 break;
1064 case DSP_MODULE_REV:
1065 revision = DSP;
1066 break;
1067 case RF_MODULE_REV:
1068 revision = ((RF_PA << 10) | (RF_PG << 7) | RF_FAM);
1069 break;
1070 default:
1071 tm_return->status = E_BADINDEX;
1072 tm_return->size = 0;
1073 return;
1074 }
1075 memcpy(tm_return->result, &revision, sizeof revision);
1076 tm_return->size = sizeof revision;
1077 tm_return->status = E_OK;
1078 }
1079
1080 /* TCS211 function missing in LoCosto, reconstructed from disassembly */
1081 void l1tm_mem_write(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1082 {
1083 UWORD8 *mem_ptr;
1084 UWORD8 num_of_bytes;
1085 UWORD16 i;
1086
1087 mem_ptr = (UWORD8 *) prim->u.mem_write.address;
1088 num_of_bytes = prim->str_len_in_bytes - 4;
1089 for (i = 0; i < num_of_bytes; i++)
1090 mem_ptr[i] = prim->u.mem_write.table[i];
1091 tm_return->size = 0;
1092 tm_return->index = 0;
1093 tm_return->status = E_OK;
1094 }
1095
1096 /* TCS211 function missing in LoCosto, reconstructed from disassembly */
1097 void l1tm_mem_read(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1098 {
1099 tm_return->index = 0;
1100 if (prim->u.mem_read.length > TM_PAYLOAD_UPLINK_SIZE_MAX - 4) {
1101 tm_return->size = 0;
1102 tm_return->status = E_BADSIZE;
1103 return;
1104 }
1105 memcpy(tm_return->result, &prim->u.mem_read.length, 4);
1106 memcpy(tm_return->result + 4, (UWORD8 *) prim->u.mem_read.src,
1107 prim->u.mem_read.length);
1108 tm_return->size = prim->u.mem_read.length + 4;
1109 tm_return->status = E_OK;
1110 }
1111
1112 /* TCS211 function missing in LoCosto, reconstructed from disassembly */
1113 void l1tm_codec_write(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1114 {
1115 UWORD16 page, reg;
1116
1117 page = (prim->u.tm_params.index >> 5) & 1;
1118 reg = prim->u.tm_params.index & 0x1F;
1119 if (!l1_config.TestMode) {
1120 tm_return->status = E_TESTMODE;
1121 goto out;
1122 }
1123 if (page >= 2 || reg >= 32) {
1124 tm_return->status = E_INVAL;
1125 goto out;
1126 }
1127 ABB_Write_Register_on_page(page + 1, reg << 1,
1128 prim->u.tm_params.value & 0x3FF);
1129 tm_return->status = E_OK;
1130 out:
1131 tm_return->index = 0;
1132 tm_return->size = 0;
1133 }
1134
1135 /* TCS211 function missing in LoCosto, reconstructed from disassembly */
1136 void l1tm_codec_read(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1137 {
1138 UWORD16 page, reg;
1139 UWORD16 value;
1140
1141 page = (prim->u.tm_params.index >> 5) & 1;
1142 reg = prim->u.tm_params.index & 0x1F;
1143 value = ABB_Read_Register_on_page(page + 1, reg << 1);
1144 memcpy(tm_return->result, &value, 2);
1145 tm_return->size = 2;
1146 tm_return->status = E_OK;
1147 tm_return->index = 0;
1148 }
1149
1150 /* TCS211 function missing in LoCosto, reconstructed from disassembly */
1151 void l1tm_misc_param_write(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1152 {
1153 tm_return->index = prim->u.tm_params.index;
1154 tm_return->size = 0;
1155 switch (prim->u.tm_params.index) {
1156 case ADC_ENA_FLAG:
1157 l1_config.adc_enable = prim->u.tm_params.value;
1158 break;
1159 default:
1160 Cust_tm_misc_param_write(tm_return, prim->u.tm_params.index,
1161 prim->u.tm_params.value);
1162 return;
1163 }
1164 tm_return->status = E_OK;
1165 }
1166
1167 /* TCS211 function missing in LoCosto, reconstructed from disassembly */
1168 void l1tm_misc_param_read(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1169 {
1170 UWORD16 value;
1171
1172 tm_return->index = prim->u.tm_params.index;
1173 switch (prim->u.tm_params.index) {
1174 case ADC_ENA_FLAG:
1175 value = l1_config.adc_enable;
1176 break;
1177 case CURRENT_TM_MODE:
1178 value = l1_config.TestMode;
1179 break;
1180 default:
1181 Cust_tm_misc_param_read(tm_return, prim->u.tm_params.index);
1182 return;
1183 }
1184 memcpy(tm_return->result, &value, 2);
1185 tm_return->size = 2;
1186 tm_return->status = E_OK;
1187 }
1188
1189 /* TCS211 function missing in LoCosto, reconstructed from disassembly */
1190 void l1tm_misc_enable(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1191 {
1192 Cust_tm_misc_enable(tm_return, prim->u.tm_params.index);
1193 }
1194
1195 void l1tm_special_param_write(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1196 {
1197 Cust_tm_special_param_write(tm_return,
1198 prim->u.tm_params.index,
1199 prim->u.tm_params.value);
1200 }
1201
1202 void l1tm_special_param_read(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1203 {
1204 Cust_tm_special_param_read(tm_return, prim->u.tm_params.index);
1205 }
1206
1207 void l1tm_special_table_write(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1208 {
1209 Cust_tm_special_table_write(tm_return,
1210 prim->u.tm_table.index,
1211 prim->str_len_in_bytes - 1,
1212 prim->u.tm_table.table);
1213 }
1214
1215 void l1tm_special_table_read(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1216 {
1217 Cust_tm_special_table_read(tm_return, prim->u.tm_table.index);
1218 }
1219
1220 void l1tm_special_enable(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1221 {
1222 Cust_tm_special_enable(tm_return, prim->u.tm_params.index);
1223 }
1224
1225 /* TCS211 function missing in LoCosto, reconstructed from disassembly */
1226 void l1tm_initialize(T_TM_RETURN *tm_return)
1227 {
1228 Cust_tm_init();
1229 tm_return->status = E_OK;
1230 tm_return->size = 0;
1231 tm_return->index = 0;
1232 }
1233
1234 /* TCS211 function missing in LoCosto, reconstructed from disassembly */
1235 void l1tm_ffs(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1236 {
1237 tm_return->size = tm_ffs(tm_return->result, 32, prim->u.ffs.packet,
1238 prim->str_len_in_bytes);
1239 tm_return->status = E_OK;
1240 tm_return->index = 0;
1241 }
1242
1243 /*-------------------------------------------------------*/
1244 /* l1tm_initialize_var() */
1245 /*-------------------------------------------------------*/
1246 /* Parameters : */
1247 /* ------------- */
1248 /* Return : */
1249 /* ------------- */
1250 /* Description : */
1251 /* ------------- */
1252 /* This routine is used to switch to TestMode by re- */
1253 /* initializing the l1a, l1s and l1a_l1s_com global */
1254 /* structures. Re-initialization is kept at a minimum. */
1255 /*-------------------------------------------------------*/
1256 void l1tm_initialize_var(void)
1257 {
1258 UWORD32 i;
1259 UWORD8 task_id;
1260
1261
1262 // L1S tasks management...
1263 //-----------------------------------------
1264 for(task_id=0; task_id<NBR_DL_L1S_TASKS; task_id++)
1265 {
1266 l1s.task_status[task_id].new_status = NOT_PENDING;
1267 l1s.task_status[task_id].current_status = INACTIVE;
1268 }
1269 l1s.frame_count = 0;
1270 l1s.forbid_meas = 0;
1271
1272 // MFTAB management variables...
1273 //-----------------------------------------
1274 l1s.afrm = 0;
1275 l1s_clear_mftab(l1s.mftab.frmlst);
1276
1277 // Flag registers for RF task controle...
1278 //-----------------------------------------
1279 l1s.tpu_ctrl_reg = 0;
1280 l1s.dsp_ctrl_reg = 0;
1281
1282 //++++++++++++++++++++++++++++++++++++++++++
1283 // Reset "l1a" structure.
1284 //++++++++++++++++++++++++++++++++++++++++++
1285
1286 // Downlink tasks management...
1287 // Uplink tasks management...
1288 // Measurement tasks management...
1289 //-----------------------------------------
1290 for(i=0; i<NBR_L1A_PROCESSES; i++)
1291 {
1292 l1a.l1a_en_meas[i] = 0;
1293 l1a.state[i] = 0; // RESET state.
1294 }
1295
1296 // Flag for forward/delete message management.
1297 //---------------------------------------------
1298 l1a.l1_msg_forwarded = 0;
1299
1300
1301 //++++++++++++++++++++++++++++++++++++++++++
1302 // Reset "l1a_l1s_com" structure.
1303 //++++++++++++++++++++++++++++++++++++++++++
1304
1305 l1a_l1s_com.l1a_activity_flag = TRUE;
1306 l1a_l1s_com.time_to_next_l1s_task = 0;
1307
1308
1309 // sleep management configuration
1310 //===============================
1311 l1s.pw_mgr.mode_authorized = NO_SLEEP;
1312
1313 // L1S scheduler...
1314 //====================
1315
1316 // L1S tasks management...
1317 //-----------------------------------------
1318 for(i=0; i<NBR_DL_L1S_TASKS; i++)
1319 {
1320 l1a_l1s_com.task_param[i] = SEMAPHORE_RESET;
1321 l1a_l1s_com.l1s_en_task[i] = TASK_DISABLED;
1322 }
1323
1324 // Measurement tasks management...
1325 //-----------------------------------------
1326 l1a_l1s_com.meas_param = 0;
1327 l1a_l1s_com.l1s_en_meas = 0;
1328
1329 #if L1_GPRS
1330 // Set DSP scheduler mode
1331 l1a_l1s_com.dsp_scheduler_mode = GSM_SCHEDULER;
1332 // Packet measurement: Reset of the frequency list.
1333 //-------------------------------------------------
1334 l1pa_reset_cr_freq_list();
1335 // Initialize active list used in Neighbour Measurement Transfer Process
1336 l1pa_l1ps_com.cres_freq_list.alist = &(l1pa_l1ps_com.cres_freq_list.list[0]);
1337
1338 l1pa_l1ps_com.transfer.semaphore = TRUE;
1339 l1pa_l1ps_com.transfer.aset = &(l1pa_l1ps_com.transfer.set[0]);
1340 l1pa_l1ps_com.transfer.fset[0] = &(l1pa_l1ps_com.transfer.set[1]);
1341 l1pa_l1ps_com.transfer.fset[1] = &(l1pa_l1ps_com.transfer.set[2]);
1342
1343 for(i=0;i<3;i++)
1344 {
1345 l1pa_l1ps_com.transfer.set[i].SignalCode = 0;
1346 l1pa_l1ps_com.transfer.set[i].dl_tbf_synchro_timeslot = 0;
1347 l1pa_l1ps_com.transfer.set[i].dl_tbf_synchro_timeslot = 0;
1348 l1pa_l1ps_com.transfer.set[i].transfer_synchro_timeslot = 0;
1349 l1pa_l1ps_com.transfer.set[i].allocated_tbf = NO_TBF;
1350 l1pa_l1ps_com.transfer.set[i].assignment_command = NO_TBF;
1351 l1pa_l1ps_com.transfer.set[i].multislot_class = 0;
1352
1353 l1pa_l1ps_com.transfer.set[i].packet_ta.ta = 255;
1354 l1pa_l1ps_com.transfer.set[i].packet_ta.ta_index = 255;
1355 l1pa_l1ps_com.transfer.set[i].packet_ta.ta_tn = 255;
1356
1357 l1pa_l1ps_com.transfer.set[i].tsc = 0;
1358
1359 l1pa_l1ps_com.transfer.set[i].freq_param.chan_sel.h = 0;
1360 l1pa_l1ps_com.transfer.set[i].freq_param.chan_sel.
1361 rf_channel.single_rf.radio_freq = 0;
1362
1363 l1pa_l1ps_com.transfer.set[i].tbf_sti.present = FALSE;
1364
1365 l1pa_l1ps_com.transfer.set[i].mac_mode = 0;
1366
1367 l1pa_l1ps_com.transfer.set[i].ul_tbf_alloc->tfi = 255;
1368 l1pa_l1ps_com.transfer.set[i].dl_tbf_alloc.tfi = 255;
1369
1370 l1pa_l1ps_com.transfer.set[i].dl_pwr_ctl.p0 = 255;
1371 l1pa_l1ps_com.transfer.set[i].dl_pwr_ctl.bts_pwr_ctl_mode = 0;
1372 l1pa_l1ps_com.transfer.set[i].dl_pwr_ctl.pr_mode = 0;
1373 }
1374 #endif
1375
1376 // Init global test mode variables
1377 l1tm.tmode_state.dedicated_active = 0;
1378 #if L1_GPRS
1379 l1tm.tmode_state.packet_transfer_active = FALSE;
1380 #endif
1381
1382 // PRBS seed initialization with a random pattern
1383 l1tm.tmode_prbs.prbs1_seed = 0x5613;
1384 }
1385
1386 void l1tm_rf_enable(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1387 {
1388 unsigned SignalCode =0;
1389 unsigned size = 0; //omaps00090550
1390 xSignalHeaderRec *msg;
1391 UWORD8 send_prim = FALSE; // Flag to send TestMode primitive...
1392 // Do not send primitive is the default; change it if necessary
1393 UWORD8 band;
1394 tm_return->index = 0; // don't include index in header
1395 #if (ETM_PROTOCOL == 1)
1396 tm_return->status = -ETM_OK;
1397 #else
1398 tm_return->status = E_OK;
1399 #endif
1400
1401 // Function only valid in TEST mode
1402 if (l1_config.TestMode == 0)
1403 {
1404 #if (ETM_PROTOCOL == 1)
1405 tm_return->status = -ETM_L1TESTMODE;
1406 #else
1407 tm_return->status = E_TESTMODE;
1408 #endif
1409 }
1410 else
1411 {
1412 // Reset all statistics
1413 l1tm_reset_rx_stats();
1414
1415 // Reset receive state counters, unless already in dedicated mode
1416 if (!l1tm.tmode_state.dedicated_active)
1417 l1tm_reset_rx_state();
1418
1419 // Reset monitor task
1420 l1_config.tmode.rf_params.mon_report = 0;
1421 l1_config.tmode.rf_params.mon_tasks = 0;
1422
1423 switch (prim->u.tm_params.index)
1424 {
1425 // Stop all RX and TX operations
1426 case STOP_ALL:
1427 {
1428 SignalCode = TMODE_STOP_RX_TX;
1429 size = sizeof(T_TMODE_STOP_RX_TX);
1430 l1tm.tmode_state.dedicated_active = 0;
1431 #if (RF_FAM == 61)
1432 // Reset the APC back to Automatic Mode
1433 l1ddsp_apc_set_automatic_mode();
1434 #endif
1435
1436 #if (RF_FAM == 35)
1437 pll_tuning.enable=0;
1438 #endif
1439 // Reset down_up flag only if not in continuous mode. If in continuous mode, down_up
1440 // will be reset after the proper TPU scenario is loaded.
1441 if (l1_config.tmode.rf_params.tmode_continuous != TM_CONTINUOUS)
1442 l1_config.tmode.rf_params.down_up = 0;
1443 send_prim = TRUE;
1444 break;
1445 }
1446 // RX with or without network synchronization first
1447 case RX_TCH:
1448 {
1449 // if already in UL-only
1450 if (l1tm.tmode_state.dedicated_active &&
1451 l1_config.tmode.rf_params.down_up == TMODE_UPLINK)
1452 {
1453 // cannot start to RX while already TXing
1454 #if (ETM_PROTOCOL == 1)
1455 tm_return->status = -ETM_AGAIN;
1456 #else
1457 tm_return->status = E_AGAIN;
1458 #endif
1459 }
1460 else
1461 {
1462 l1_config.tmode.rf_params.down_up = TMODE_DOWNLINK;
1463 SignalCode = TMODE_IMMED_ASSIGN_REQ;
1464 size = sizeof(T_TMODE_IMMED_ASSIGN_REQ);
1465 send_prim = TRUE;
1466 }
1467 break;
1468 }
1469 // TX NB's or AB's on TCH with or without network synch. first
1470 case TX_TCH:
1471 {
1472 // Normal burst TX
1473 if (l1_config.tmode.tx_params.burst_type == 0)
1474 {
1475 // if already in DL-only, add UL
1476 if (l1tm.tmode_state.dedicated_active &&
1477 l1_config.tmode.rf_params.down_up == TMODE_DOWNLINK)
1478 {
1479 l1_config.tmode.rf_params.down_up = (TMODE_DOWNLINK | TMODE_UPLINK);
1480 }
1481 else
1482 {
1483 l1_config.tmode.rf_params.down_up = TMODE_UPLINK;
1484 SignalCode = TMODE_IMMED_ASSIGN_REQ;
1485 size = sizeof(T_TMODE_IMMED_ASSIGN_REQ);
1486 send_prim = TRUE;
1487 }
1488 }
1489 // AB TX
1490 else if (l1_config.tmode.tx_params.burst_type == 1)
1491 {
1492 // cannot start RACH while already in dedicated mode
1493 if (l1tm.tmode_state.dedicated_active)
1494 {
1495 #if (ETM_PROTOCOL == 1)
1496 tm_return->status = -ETM_AGAIN;
1497 #else
1498 tm_return->status = E_AGAIN;
1499 #endif
1500 }
1501 else
1502 {
1503 SignalCode = TMODE_RA_START;
1504 size = sizeof(TMODE_RA_START);
1505 send_prim = TRUE;
1506 }
1507 }
1508 break;
1509 }
1510 // RX & TX on TCH with or without network synch. first
1511 case RX_TX_TCH:
1512 {
1513 // if NB TX
1514 if (l1_config.tmode.tx_params.burst_type == 0)
1515 {
1516 // if already in DL-only, add UL
1517 if (l1tm.tmode_state.dedicated_active &&
1518 l1_config.tmode.rf_params.down_up == TMODE_DOWNLINK)
1519 {
1520 l1_config.tmode.rf_params.down_up = (TMODE_DOWNLINK | TMODE_UPLINK);
1521 }
1522 // else if already in UL-only
1523 else if (l1tm.tmode_state.dedicated_active &&
1524 l1_config.tmode.rf_params.down_up == TMODE_UPLINK)
1525 {
1526 // cannot start to RX while already TXing
1527 #if (ETM_PROTOCOL == 1)
1528 tm_return->status = -ETM_AGAIN;
1529 #else
1530 tm_return->status = E_AGAIN;
1531 #endif
1532 }
1533 else
1534 {
1535 l1_config.tmode.rf_params.down_up = (TMODE_DOWNLINK | TMODE_UPLINK);
1536 SignalCode = TMODE_IMMED_ASSIGN_REQ;
1537 size = sizeof(T_TMODE_IMMED_ASSIGN_REQ);
1538 send_prim = TRUE;
1539 }
1540 }
1541 // else if AB TX
1542 else if (l1_config.tmode.tx_params.burst_type == 1)
1543 {
1544 // Cannot TX RACH and RX simultaneously
1545 #if (ETM_PROTOCOL == 1)
1546 tm_return->status = -ETM_AGAIN;
1547 #else
1548 tm_return->status = E_AGAIN;
1549 #endif
1550 }
1551 break;
1552 }
1553 // Continuous (all timeslots) reception on TCH
1554 case RX_TCH_CONT:
1555 {
1556 // if already in UL, DL or UL+DL
1557 if (l1tm.tmode_state.dedicated_active &&
1558 l1_config.tmode.rf_params.down_up != 0)
1559 {
1560 // cannot start to continously RX while already TXing or RXing
1561 #if (ETM_PROTOCOL == 1)
1562 tm_return->status = -ETM_AGAIN;
1563 #else
1564 tm_return->status = E_AGAIN;
1565 #endif
1566 }
1567 else
1568 {
1569 l1_config.tmode.rf_params.tmode_continuous = TM_START_RX_CONTINUOUS;
1570 l1_config.tmode.rf_params.down_up = TMODE_DOWNLINK;
1571 SignalCode = TMODE_IMMED_ASSIGN_REQ;
1572 size = sizeof(T_TMODE_IMMED_ASSIGN_REQ);
1573 send_prim = TRUE;
1574 }
1575 break;
1576 }
1577 // continuous (all timeslots) transmission
1578 case TX_TCH_CONT:
1579 {
1580 // PCS 1900 not supported yet.
1581 #if (L1_FF_MULTIBAND == 0)
1582 band = ((l1_config.tmode.rf_params.tch_arfcn >= 512) &&
1583 (l1_config.tmode.rf_params.tch_arfcn <= 885));
1584 #else
1585 band = ( ((l1_config.tmode.rf_params.tch_arfcn >= 512) &&
1586 (l1_config.tmode.rf_params.tch_arfcn <= 885)) ||
1587 ((l1_config.tmode.rf_params.tch_arfcn >= 1024) &&
1588 (l1_config.tmode.rf_params.tch_arfcn <= 1322)) );
1589 #endif
1590
1591 // if already in UL, DL or UL+DL
1592 if ((l1tm.tmode_state.dedicated_active && l1_config.tmode.rf_params.down_up != 0) ||
1593 (band == 0 && (l1_config.tmode.tx_params.txpwr < (5 + l1_config.tmode.tx_params.txpwr_skip))) ||
1594 (band == 1 && (l1_config.tmode.tx_params.txpwr < (0 + l1_config.tmode.tx_params.txpwr_skip))))
1595 {
1596 // cannot start to continously TX while already TXing or RXing
1597 // or while adc reading are enabled
1598 #if (ETM_PROTOCOL == 1)
1599 tm_return->status = -ETM_INVAL;
1600 #else
1601 tm_return->status = E_INVAL;
1602 #endif
1603 }
1604 else
1605 {
1606 #if (RF_FAM == 61)
1607 // Set APC in Manual Mode
1608 l1ddsp_apc_set_manual_mode();
1609 #endif
1610 l1_config.tmode.rf_params.tmode_continuous = TM_START_TX_CONTINUOUS;
1611 l1_config.tmode.rf_params.down_up = TMODE_UPLINK;
1612 SignalCode = TMODE_IMMED_ASSIGN_REQ;
1613 size = sizeof(T_TMODE_IMMED_ASSIGN_REQ);
1614 send_prim = TRUE;
1615 }
1616 break;
1617 }
1618 // Continuous BCCH
1619 case BCCH_LOOP:
1620 {
1621 SignalCode = TMODE_SCELL_NBCCH_REQ;
1622 size = sizeof(TMODE_SCELL_NBCCH_REQ);
1623 send_prim = TRUE;
1624 break;
1625 }
1626 // Continuous SB
1627 case SB_LOOP:
1628 {
1629 SignalCode = TMODE_SB_REQ;
1630 size = sizeof(T_TMODE_SB_REQ);
1631 send_prim = TRUE;
1632 break;
1633 }
1634 // Continuous FB1
1635 case FB1_LOOP:
1636 {
1637 SignalCode = TMODE_FB1_REQ;
1638 size = sizeof(T_TMODE_FB1_REQ);
1639 send_prim = TRUE;
1640 break;
1641 }
1642 // Continuous FB0
1643 case FB0_LOOP:
1644 {
1645 SignalCode = TMODE_FB0_REQ;
1646 size = sizeof(T_TMODE_FB0_REQ);
1647 send_prim = TRUE;
1648 break;
1649 }
1650 // TX + RX + MON on TCH
1651 case RX_TX_MON_TCH: // Stats collected from TCH Channel.
1652 case RX_TX_MON: // Stats collected from MON Channel (except rxlev).
1653 {
1654 // Normal burst uplink
1655 if (l1_config.tmode.tx_params.burst_type == 0)
1656 {
1657 // If already in dedicated mode, return error
1658 if (l1tm.tmode_state.dedicated_active)
1659 {
1660 #if (ETM_PROTOCOL == 1)
1661 tm_return->status = -ETM_AGAIN;
1662 #else
1663 tm_return->status = E_AGAIN;
1664 #endif
1665 }
1666 else
1667 {
1668 l1_config.tmode.rf_params.down_up = (TMODE_DOWNLINK | TMODE_UPLINK);
1669 l1_config.tmode.rf_params.mon_report = ((prim->u.tm_params.index & 0x08) >> 3);
1670 l1_config.tmode.rf_params.mon_tasks = 1; // enable MON tasks
1671 SignalCode = TMODE_IMMED_ASSIGN_REQ;
1672 size = sizeof(T_TMODE_IMMED_ASSIGN_REQ);
1673 send_prim = TRUE;
1674 }
1675 }
1676 // else if Access burst uplink
1677 else if (l1_config.tmode.tx_params.burst_type == 1)
1678 {
1679 // Cannot TX RACH and RX simultaneously
1680 #if (ETM_PROTOCOL == 1)
1681 tm_return->status = -ETM_AGAIN;
1682 #else
1683 tm_return->status = E_AGAIN;
1684 #endif
1685 }
1686 break;
1687 }
1688 case SINGLE_PM:
1689 {
1690 SignalCode = TMODE_RXLEV_REQ;
1691 size = sizeof(T_TMODE_RXLEV_REQ);
1692 send_prim = TRUE;
1693 break;
1694 }
1695 #if L1_GPRS
1696 // RX & TX on PDTCH with or without network synch. first
1697 case RX_TX_PDTCH:
1698 {
1699 UWORD8 bit_map = 0x80;
1700
1701 // set uplink + downlink
1702 if (l1_config.tmode.tx_params.timeslot_alloc)
1703 l1_config.tmode.rf_params.down_up = TMODE_DOWNLINK | TMODE_UPLINK;
1704 else
1705 l1_config.tmode.rf_params.down_up = TMODE_DOWNLINK;
1706
1707 while (bit_map)
1708 {
1709 if (bit_map & l1_config.tmode.stats_config.stat_gprs_slots)
1710 l1tm.tmode_stats.nb_dl_pdtch_slots ++;
1711
1712 bit_map>>=1;
1713 }
1714
1715 SignalCode = TMODE_PDTCH_ASSIGN_REQ;
1716 size = sizeof(T_TMODE_PDTCH_ASSIGN_REQ);
1717 send_prim = TRUE;
1718 break;
1719 }
1720 #endif
1721 #if L1_GPRS
1722 // RX & TX on PDTCH, FB on monitor arfcn
1723 case RX_TX_PDTCH_MON:
1724 {
1725 // set uplink + downlink
1726 if (l1_config.tmode.tx_params.timeslot_alloc)
1727 l1_config.tmode.rf_params.down_up = TMODE_DOWNLINK | TMODE_UPLINK;
1728 else
1729 l1_config.tmode.rf_params.down_up = TMODE_DOWNLINK;
1730
1731 l1_config.tmode.rf_params.mon_report = 1; // collect stats from MON channel
1732 l1_config.tmode.rf_params.mon_tasks = 1; // enable MON tasks
1733
1734 SignalCode = TMODE_PDTCH_ASSIGN_REQ;
1735 size = sizeof(T_TMODE_PDTCH_ASSIGN_REQ);
1736 send_prim = TRUE;
1737 break;
1738 }
1739 #endif
1740 #if (RF_FAM == 35)
1741 case RX_PLL_TUNING:
1742 {
1743 // if already in UL-only
1744 if (l1tm.tmode_state.dedicated_active &&
1745 l1_config.tmode.rf_params.down_up == TMODE_UPLINK)
1746 {
1747 // cannot start to RX while already TXing
1748 #if (ETM_PROTOCOL == 1)
1749 tm_return->status = -ETM_AGAIN;
1750 #else
1751 tm_return->status = E_AGAIN;
1752 #endif
1753 }
1754 else
1755 {
1756 pll_tuning.data[5] = 0;
1757 pll_tuning.index = 0;
1758
1759 pll_tuning.enable = 1;
1760
1761 l1_config.tmode.rf_params.down_up = TMODE_DOWNLINK;
1762 SignalCode = TMODE_IMMED_ASSIGN_REQ;
1763 size = sizeof(T_TMODE_IMMED_ASSIGN_REQ);
1764 send_prim = TRUE;
1765 }
1766 break;
1767 }
1768 #endif
1769 default:
1770 {
1771 #if (ETM_PROTOCOL == 1)
1772 tm_return->status = -ETM_INVAL;
1773 #else
1774 tm_return->status = E_BADINDEX;
1775 #endif
1776 break;
1777 }
1778 } //end switch
1779 } // end of else
1780
1781 if (send_prim == TRUE)
1782 {
1783 // Allocate result message.
1784 msg = os_alloc_sig(size);
1785 DEBUGMSG(status,NU_ALLOC_ERR)
1786 msg->SignalCode = SignalCode;
1787 os_send_sig(msg, L1C1_QUEUE);
1788 DEBUGMSG(status,NU_SEND_QUEUE_ERR)
1789 }
1790
1791 // always return a 0 in the result[], even if error
1792 tm_return->result[0] = 0;
1793 tm_return->size = 1;
1794 }
1795
1796
1797 void l1tm_stats_config_write(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1798 {
1799 tm_return->index = prim->u.tm_params.index;
1800 tm_return->size = 0;
1801
1802 switch (prim->u.tm_params.index)
1803 {
1804 case LOOPS:
1805 {
1806 l1_config.tmode.stats_config.num_loops = prim->u.tm_params.value;
1807 #if (ETM_PROTOCOL == 1)
1808 tm_return->status = -ETM_OK;
1809 #else
1810 tm_return->status = E_OK;
1811 #endif
1812 break;
1813 }
1814 case AUTO_RESULT_LOOPS:
1815 {
1816 l1_config.tmode.stats_config.auto_result_loops = prim->u.tm_params.value;
1817 #if (ETM_PROTOCOL == 1)
1818 tm_return->status = -ETM_OK;
1819 #else
1820 tm_return->status = E_OK;
1821 #endif
1822 break;
1823 }
1824 case AUTO_RESET_LOOPS:
1825 {
1826 l1_config.tmode.stats_config.auto_reset_loops = prim->u.tm_params.value;
1827 #if (ETM_PROTOCOL == 1)
1828 tm_return->status = -ETM_OK;
1829 #else
1830 tm_return->status = E_OK;
1831 #endif
1832 break;
1833 }
1834 case STAT_TYPE:
1835 {
1836 l1_config.tmode.stats_config.stat_type = prim->u.tm_params.value;
1837 #if (ETM_PROTOCOL == 1)
1838 tm_return->status = -ETM_OK;
1839 #else
1840 tm_return->status = E_OK;
1841 #endif
1842 break;
1843 }
1844 case STAT_BITMASK:
1845 {
1846 l1_config.tmode.stats_config.stat_bitmask = prim->u.tm_params.value;
1847 #if (ETM_PROTOCOL == 1)
1848 tm_return->status = -ETM_OK;
1849 #else
1850 tm_return->status = E_OK;
1851 #endif
1852 break;
1853 }
1854 #if L1_GPRS
1855 case STAT_GPRS_SLOTS:
1856 {
1857 UWORD8 allocation, value;
1858
1859 value = prim->u.tm_params.value;
1860
1861 // Check for mismatch between DL TS allocation and stats bitmap
1862 allocation = value ^ l1_config.tmode.rx_params.timeslot_alloc;
1863
1864 if (value & allocation)
1865 #if (ETM_PROTOCOL == 1)
1866 tm_return->status = -ETM_INVAL;
1867 #else
1868 tm_return->status = E_INVAL;
1869 #endif
1870 else
1871 {
1872 l1_config.tmode.stats_config.stat_gprs_slots = value;
1873 #if (ETM_PROTOCOL == 1)
1874 tm_return->status = -ETM_OK;
1875 #else
1876 tm_return->status = E_OK;
1877 #endif
1878 }
1879 break;
1880 }
1881 #endif
1882 default:
1883 {
1884 #if (ETM_PROTOCOL == 1)
1885 tm_return->status = -ETM_INVAL;
1886 #else
1887 tm_return->status = E_BADINDEX;
1888 #endif
1889 break;
1890 }
1891 } // end switch
1892 }
1893
1894 void l1tm_stats_config_read(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1895 {
1896 volatile UWORD16 value;
1897
1898 tm_return->index = prim->u.tm_params.index;
1899
1900 switch (prim->u.tm_params.index)
1901 {
1902 case LOOPS:
1903 {
1904 value = l1_config.tmode.stats_config.num_loops;
1905 break;
1906 }
1907 case AUTO_RESULT_LOOPS:
1908 {
1909 value = l1_config.tmode.stats_config.auto_result_loops;
1910 break;
1911 }
1912 case AUTO_RESET_LOOPS:
1913 {
1914 value = l1_config.tmode.stats_config.auto_reset_loops;
1915 break;
1916 }
1917 case STAT_TYPE:
1918 {
1919 value = l1_config.tmode.stats_config.stat_type;
1920 break;
1921 }
1922 case STAT_BITMASK:
1923 {
1924 value = l1_config.tmode.stats_config.stat_bitmask;
1925 break;
1926 }
1927 #if L1_GPRS
1928 case STAT_GPRS_SLOTS:
1929 {
1930 value = l1_config.tmode.stats_config.stat_gprs_slots;
1931 break;
1932 }
1933 #endif
1934 default:
1935 {
1936 #if (ETM_PROTOCOL == 1)
1937 tm_return->status = -ETM_INVAL;
1938 #else
1939 tm_return->status = E_BADINDEX;
1940 #endif
1941 tm_return->size = 0;
1942 return;
1943 }
1944 } // end switch
1945
1946 memcpy(tm_return->result, (UWORD8 *) &value, 2);
1947 tm_return->size = 2;
1948 #if (ETM_PROTOCOL == 1)
1949 tm_return->status = -ETM_OK;
1950 #else
1951 tm_return->status = E_OK;
1952 #endif
1953 }
1954
1955 void l1tm_statistics(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
1956 {
1957 l1tm_stats_read(tm_return,
1958 prim->u.tm_params.index,
1959 prim->u.tm_params.value);
1960 }
1961
1962 #if L1_GPRS
1963 void l1tm_rlc_uplink(UWORD8 tx, API *ul_data)
1964 {
1965 // Cast the ul_data_buffer
1966 typedef struct
1967 {
1968 API a_ul_data[4][29];
1969 }
1970 T_A_UL_DATA;
1971
1972 T_A_UL_DATA *ptr = (T_A_UL_DATA*) ul_data;
1973 UWORD8 i,j;
1974
1975 for (j=0; j<tx; j++)
1976 {
1977 ptr->a_ul_data[j][0] = l1_config.tmode.tx_params.coding_scheme;
1978
1979 for (i=0;i<l1_config.tmode.tx_params.rlc_buffer_size;i++)
1980 ptr->a_ul_data[j][i+1] = l1_config.tmode.tx_params.rlc_buffer[i];
1981 }
1982 }
1983 #endif
1984
1985 void l1tm_stats_read(T_TM_RETURN *tm_return, WORD16 type, UWORD16 bitmask)
1986 {
1987 extern T_L1A_L1S_COM l1a_l1s_com;
1988 extern T_L1S_GLOBAL l1s;
1989 volatile UWORD32 utemp = bitmask, temp_U32;
1990 volatile WORD32 temp = type;
1991 volatile WORD32 value_signed_int;
1992 volatile UWORD32 value_unsigned_int;
1993 volatile UWORD16 value_unsigned_short;
1994 UWORD8 j, offset=0; // offset is index of tm_return->result[]
1995 UWORD16 rssi, len;
1996 WORD32 count;
1997 WORD32 runs = l1tm.tmode_stats.loop_count;
1998
1999 /*
2000 * FreeCalypso TCS211 reconstruction: the following automatic var
2001 * is for the BLER code we have conditioned out below.
2002 */
2003 #if 0 //L1_GPRS
2004 volatile UWORD16 value_array_unsigned_short[4];
2005 #endif
2006
2007 // Put type and bitmask in the front of tm_return->result[].
2008 // Use volatile vars for proper operation of memcpy().
2009 memcpy(&tm_return->result[offset], (UWORD8 *) &temp, 2);
2010 offset+=2;
2011 memcpy(&tm_return->result[offset], (UWORD8 *) &utemp, 2);
2012 offset+=2;
2013
2014 switch (type)
2015 {
2016 // Accumulated receive burst stats
2017 case ACCUMULATED_RX_STATS:
2018 {
2019 // all stats saved when collected from TCH
2020 if (l1tm.tmode_state.dedicated_active && (l1_config.tmode.rf_params.mon_report == 0))
2021 count = l1tm.tmode_stats.loop_count;
2022 #if L1_GPRS
2023 else if (l1tm.tmode_state.packet_transfer_active && (l1_config.tmode.rf_params.mon_report == 0))
2024 {
2025 // loop_count contains the number of blocks
2026 // Stats (PM, TOA, SNR, ANGLE) are accumulated over all frames and all time slots
2027 count = l1tm.tmode_stats.loop_count * l1tm.tmode_stats.nb_dl_pdtch_slots * 4;
2028
2029 // the count of runs vs. successes is accumulated over all time slots per block
2030 runs = l1tm.tmode_stats.loop_count * l1tm.tmode_stats.nb_dl_pdtch_slots;
2031 }
2032 #endif
2033 else count = l1tm.tmode_stats.flag_count; // only PASS stats saved
2034
2035 if (bitmask & RSSI) // rxlev: RSSI SF12.4 eventually (currently F7.1)
2036 {
2037 len = sizeof(l1tm.tmode_stats.rssi_fifo) / sizeof(l1tm.tmode_stats.rssi_fifo[0]);
2038 rssi = 0;
2039 for (j=0; j<len; j++)
2040 rssi += l1tm.tmode_stats.rssi_fifo[j];
2041 rssi /= len; // F7.1
2042 memcpy(&tm_return->result[offset], (UWORD8 *) &rssi, 2);
2043 offset+=2;
2044 }
2045 // pm: DSP MEAN power measurement UF10.6
2046 if (bitmask & DSP_PM)
2047 {
2048 if (count)
2049 value_unsigned_short = l1tm.tmode_stats.pm_sum / count;
2050 else value_unsigned_short = 0;
2051 memcpy(&tm_return->result[offset], (UWORD8 *) &value_unsigned_short, 2);
2052 offset+=2;
2053 }
2054 // angle mean
2055 if (bitmask & ANGLE_MEAN)
2056 {
2057 if (count) // non-zero
2058 value_signed_int = l1tm.tmode_stats.angle_sum / count;
2059 else value_signed_int = 0;
2060 memcpy(&tm_return->result[offset], (UWORD8 *) &value_signed_int, 4);
2061 offset+=4;
2062 }
2063 // angle variance
2064 if (bitmask & ANGLE_VAR)
2065 {
2066 // VAR[X] = E[X^2] - (E[X])^2
2067 if (count) // non-zero
2068 {
2069 temp_U32 = l1tm.tmode_stats.angle_sum / count;
2070 value_unsigned_int = l1tm.tmode_stats.angle_sq_sum / count - (temp_U32)*(temp_U32);
2071 }
2072 else value_unsigned_int = 0;
2073 memcpy(&tm_return->result[offset], (UWORD8 *) &value_unsigned_int, 4);
2074 offset+=4;
2075 }
2076 // angle minimum
2077 if (bitmask & ANGLE_MIN)
2078 {
2079 value_signed_int = l1tm.tmode_stats.angle_min;
2080 memcpy(&tm_return->result[offset], (UWORD8 *) &value_signed_int, 4);
2081 offset+=4;
2082 }
2083 // angle maximum
2084 if (bitmask & ANGLE_MAX)
2085 {
2086 value_signed_int = l1tm.tmode_stats.angle_max;
2087 memcpy(&tm_return->result[offset], (UWORD8 *) &value_signed_int, 4);
2088 offset+=4;
2089 }
2090 // SNR mean
2091 if (bitmask & SNR_MEAN)
2092 {
2093 if (count) // non-zero
2094 value_unsigned_int = l1tm.tmode_stats.snr_sum / count;
2095 else value_unsigned_int = 0;
2096 memcpy(&tm_return->result[offset], (UWORD8 *) &value_unsigned_int, 4);
2097 offset+=4;
2098 }
2099 // SNR variance
2100 if (bitmask & SNR_VAR)
2101 {
2102 if (count) // non-zero
2103 {
2104 temp_U32 = l1tm.tmode_stats.snr_sum / count;
2105 value_unsigned_int = l1tm.tmode_stats.snr_sq_sum / count -
2106 temp_U32 * temp_U32;
2107 }
2108 else
2109 value_unsigned_int = 0;
2110 memcpy(&tm_return->result[offset], (UWORD8 *) &value_unsigned_int, 4);
2111 offset+=4;
2112 }
2113 // TOA mean
2114 if (bitmask & TOA_MEAN)
2115 {
2116 if (count) // non-zero
2117 value_unsigned_int = l1tm.tmode_stats.toa_sum / count;
2118 else value_unsigned_int = 0;
2119 memcpy(&tm_return->result[offset], (UWORD8 *) &value_unsigned_int, 4);
2120 offset+=4;
2121 }
2122 // TOA variance
2123 if (bitmask & TOA_VAR)
2124 {
2125 if (count) // non-zero
2126 {
2127 temp_U32 = l1tm.tmode_stats.toa_sum / count;
2128 value_unsigned_int = l1tm.tmode_stats.toa_sq_sum / count -
2129 temp_U32 * temp_U32;
2130 }
2131 else value_unsigned_int = 0;
2132 memcpy(&tm_return->result[offset], (UWORD8 *) &value_unsigned_int, 4);
2133 offset+=4;
2134 }
2135 // Frame # mod 26*51
2136 if (bitmask & FRAME_NUMBER)
2137 {
2138 value_unsigned_int = l1s.actual_time.fn;
2139 memcpy(&tm_return->result[offset], (UWORD8 *) &value_unsigned_int, 4);
2140 offset+=4;
2141 }
2142 // Tot # of runs executed so far
2143 if (bitmask & RUNS)
2144 {
2145 memcpy(&tm_return->result[offset], (UWORD8 *) &runs, 4);
2146 offset+=4;
2147 }
2148 // Tot # of successes so far
2149 if (bitmask & SUCCESSES)
2150 {
2151 memcpy(&tm_return->result[offset], (UWORD8 *) &l1tm.tmode_stats.flag_count, 4);
2152 offset+=4;
2153 }
2154 // BSIC
2155 if (bitmask & BSIC)
2156 {
2157 value_unsigned_short = l1tm.tmode_stats.bsic;
2158 memcpy(&tm_return->result[offset], (UWORD8 *) &value_unsigned_short, 2);
2159 offset+=2;
2160 }
2161
2162 /*
2163 * FreeCalypso TCS211 reconstruction: suspected LoCosto-ism,
2164 * removing in order to pass compilation.
2165 */
2166 #if 0 //L1_GPRS
2167 if (bitmask & BLER)
2168 {
2169 UWORD8 j;
2170 if (count) // non-zero
2171 {
2172 float bler, remain_part;
2173 UWORD8 int_part, bitmap_remain;
2174 int i;
2175
2176 //compute bler for each block
2177 for (j=0; j<4; j++)
2178 {
2179 bler = ((float) (l1tm.tmode_stats.bler_crc[j] * 100)) / ((float) l1tm.tmode_stats.bler_total_blocks);
2180
2181 //conversion from floating to fixed format
2182 int_part = (UWORD8) bler;
2183 remain_part = bler - (float) int_part;
2184 bitmap_remain = 0;
2185
2186 i=5;
2187 while (i >= 0)
2188 {
2189 bitmap_remain |= (UWORD8) (remain_part *2) << i;
2190 if (((UWORD8) (remain_part *2)) >= 1)
2191 remain_part = (remain_part * 2) - 1;
2192 else
2193 remain_part = (remain_part * 2);
2194 i--;
2195 }
2196
2197 // Reporting the percentage of blocks in error (F10.6)
2198 value_array_unsigned_short[j] = bitmap_remain | (int_part << 6);
2199 }
2200 }
2201 // Reporting a BLER of 100, if no computation has been done
2202 else
2203 {
2204 for (j=0; j<4; j++)
2205 value_array_unsigned_short[j] = 100 << 6;
2206 }
2207 memcpy(&tm_return->result[offset], (UWORD8 *) &value_array_unsigned_short[0], 8);
2208 offset+=8;
2209 }
2210 #endif
2211
2212
2213 #if (ETM_PROTOCOL == 1)
2214 tm_return->status = -ETM_OK;
2215 #else
2216 tm_return->status = E_OK;
2217 #endif
2218 break;
2219 }
2220 // Most recent receive burst stats
2221 case MOST_RECENT_RX_STATS:
2222 {
2223 // rxlev: RSSI SF12.4 eventually (F7.1 currently)
2224 if (bitmask & RSSI)
2225 {
2226 value_unsigned_short = l1tm.tmode_stats.rssi_recent;
2227 memcpy(&tm_return->result[offset], (UWORD8 *) &value_unsigned_short, 2);
2228 offset+=2;
2229 }
2230 // pm: most recent DSP power measurement UF10.6
2231 if (bitmask & DSP_PM)
2232 {
2233 memcpy(&tm_return->result[offset], &l1tm.tmode_stats.pm_recent, 2);
2234 offset+=2;
2235 }
2236 // most recent ANGLE value
2237 if (bitmask & ANGLE_MEAN)
2238 {
2239 value_signed_int = l1tm.tmode_stats.angle_recent;
2240 memcpy(&tm_return->result[offset], (UWORD8 *) &value_signed_int, 4);
2241 offset+=4;
2242 }
2243 // doesn't make sense.
2244 if (bitmask & ANGLE_VAR)
2245 {
2246 }
2247 // doesn't make sense.
2248 if (bitmask & ANGLE_MIN)
2249 {
2250 }
2251 // doesn't make sense.
2252 if (bitmask & ANGLE_MAX)
2253 {
2254 }
2255 // most recent SNR value
2256 if (bitmask & SNR_MEAN)
2257 {
2258 value_unsigned_int = l1tm.tmode_stats.snr_recent;
2259 memcpy(&tm_return->result[offset], (UWORD8 *) &value_unsigned_int, 4);
2260 offset+=4;
2261 }
2262 // doesn't make sense.
2263 if (bitmask & SNR_VAR)
2264 {
2265 }
2266 // most recent TOA value
2267 if (bitmask & TOA_MEAN)
2268 {
2269 value_unsigned_int = l1tm.tmode_stats.toa_recent;
2270 memcpy(&tm_return->result[offset], (UWORD8 *) &value_unsigned_int, 4);
2271 offset+=4;
2272 }
2273 // doesn't make sense.
2274 if (bitmask & TOA_VAR)
2275 {
2276 }
2277 // Frame # mod 26*51
2278 if (bitmask & FRAME_NUMBER)
2279 {
2280 value_unsigned_int = l1s.actual_time.fn;
2281 memcpy(&tm_return->result[offset], (UWORD8 *) &value_unsigned_int, 4);
2282 offset+=4;
2283 }
2284 // must be '1'
2285 if (bitmask & RUNS)
2286 {
2287 }
2288 // most recent Success flag
2289 if (bitmask & SUCCESSES)
2290 {
2291 memcpy(&tm_return->result[offset], (UWORD8 *)&l1tm.tmode_stats.flag_recent, 4);
2292 offset+=4;
2293 }
2294 // BSIC
2295 if (bitmask & BSIC)
2296 {
2297 value_unsigned_short = l1tm.tmode_stats.bsic;
2298 memcpy(&tm_return->result[offset], (UWORD8 *) &value_unsigned_short, 2);
2299 offset+=2;
2300 }
2301 #if (ETM_PROTOCOL == 1)
2302 tm_return->status = -ETM_OK;
2303 #else
2304 tm_return->status = E_OK;
2305 #endif
2306 break;
2307 }
2308 default:
2309 {
2310 #if (ETM_PROTOCOL == 1)
2311 tm_return->status = -ETM_INVAL;
2312 #else
2313 tm_return->status = E_BADINDEX;
2314 #endif
2315 break;
2316 }
2317 } // end switch
2318
2319 tm_return->size = offset;
2320 tm_return->index = 0; // don't include index in header
2321 }
2322
2323 /*-------------------------------------------------------*/
2324 /* l1tm_fill_burst() */
2325 /*-------------------------------------------------------*/
2326 /* */
2327 /* Description: Prepare bursts for transmission in case */
2328 /* ------------ of UL test */
2329 /* */
2330 /* Simulation of IQ Swap does the following mapping: */
2331 /* */
2332 /* 00 -> 01 */
2333 /* 01 -> 00 */
2334 /* 10 -> 11 */
2335 /* 11 -> 10 */
2336 /* */
2337 /*-------------------------------------------------------*/
2338 #if (L1_FF_MULTIBAND == 1)
2339 extern const WORD8 rf_subband2band[];
2340 #endif
2341 void l1tm_fill_burst (UWORD16 pattern, UWORD16 *TM_ul_data)
2342 {
2343 UWORD32 i;
2344 UWORD8 swap_iq, swap_flag;
2345 UWORD16 gb_front, gb_end, tb_front, tb_end, even_bits, odd_bits;
2346 #if (L1_FF_MULTIBAND == 1)
2347 UWORD8 physical_band_id;
2348 #endif
2349 UWORD8 tsc_bits_in_first_word;
2350 UWORD16 tsc_front_mask,tsc_end_mask;
2351 extern T_RF rf;
2352
2353 // training sequences list......
2354 UWORD32 tsc[8]=
2355 {
2356 0x00970897,
2357 0x00B778B7,
2358 0x010EE90E,
2359 0x011ED11E,
2360 0x006B906B,
2361 0x013AC13A,
2362 0x029F629F,
2363 0x03BC4BBC
2364 };
2365 #if (L1_FF_MULTIBAND == 0)
2366
2367 if(((l1_config.std.id == DUAL) || (l1_config.std.id == DUALEXT) || (l1_config.std.id == DUAL_US)) &&
2368 (l1_config.tmode.rf_params.tch_arfcn >= l1_config.std.first_radio_freq_band2))
2369 {
2370 swap_iq = l1_config.std.swap_iq_band2;
2371 }
2372 else
2373 {
2374 swap_iq = l1_config.std.swap_iq_band1;
2375 }
2376
2377 #else // L1_FF_MULTIBAND = 1 below
2378
2379 physical_band_id =
2380 rf_subband2band[rf_convert_rffreq_to_l1subband(l1_config.tmode.rf_params.tch_arfcn)];
2381
2382 swap_iq = rf_band[physical_band_id].swap_iq;
2383
2384 #endif // #if (L1_FF_MULTIBAND == 0) else
2385
2386 // Swap IQ definitions...
2387 // 0=No Swap, 1=Swap RX only, 2=Swap TX only, 3=Swap RX and TX
2388 if (swap_iq & 0x2)
2389 {
2390 swap_flag = 1;
2391 }
2392 else
2393 {
2394 swap_flag = 0;
2395 }
2396
2397 //===========================================
2398 // define uplink patterns
2399 //===========================================
2400 if (pattern == 0) // 0's
2401 pattern = 0x0000;
2402 else if (pattern == 1) // 1's
2403 pattern = 0xffff;
2404 else if (pattern == 2) // 01's
2405 pattern = 0x5555;
2406
2407 // first replicate pattern through all buffer
2408 if ((pattern == 3) || (pattern == 4))
2409 {
2410 // fill the uplink burst with PRBS1
2411 l1tm_PRBS1_generate(TM_ul_data);
2412 }
2413 else if ((pattern != 12) && (pattern != 13))
2414 {
2415 for (i=0;i<=15;i++)
2416 TM_ul_data[i] = (pattern << 6);
2417 }
2418
2419 //===========================================
2420 // create front-end guard and tail bits masks
2421 //===========================================
2422 // guard bits mask
2423 gb_front = 0xFFC0 << (10 - rf.tx.guard_bits); // max. of 10, min. of 2 guard bits allowed
2424
2425 // check if guard bits > 7
2426 if (rf.tx.guard_bits > 7)
2427 {
2428 // tail bits mask
2429 tb_front = ~((UWORD16)(0xE000 << (10 - rf.tx.guard_bits))) & 0xFFC0; // tail bits placed in TM_ul_data[1] //oamps00090550
2430 // add tail bits to uplink data
2431 TM_ul_data[1] = TM_ul_data[1] & tb_front;
2432 // add guard bits to uplink data
2433 TM_ul_data[0] = gb_front;
2434 }
2435 else
2436 {
2437 // tail bits mask
2438 tb_front = ~((UWORD16)(0xE000 >> rf.tx.guard_bits) )& 0xFFC0; // 3 tail bits
2439 // add tail bits to uplink data
2440 TM_ul_data[0] = (TM_ul_data[0] | gb_front) & tb_front;
2441 }
2442
2443 //===========================================
2444 // create back-end guard and tail bits masks
2445 //===========================================
2446 // guard bits mask
2447 gb_end = (0xFFC0 >> (10 - (12 - rf.tx.guard_bits))) & 0xFFC0; // max. of 10, min. of 2 guard bits allowed
2448
2449 // check if guard bits < 5
2450 if (rf.tx.guard_bits < 5)
2451 {
2452 //tail bits mask
2453 tb_end = ~(UWORD16)((0x01C0 >> (rf.tx.guard_bits - 2))) & 0xFFC0; // tail bits placed in TM_ul_data[14]
2454 // add tail bits to uplink data
2455 TM_ul_data[14] = TM_ul_data[14] & tb_end;
2456 // add guard bits to uplink data
2457 TM_ul_data[15] = gb_end;
2458 }
2459 else
2460 {
2461 // tail bits mask
2462 tb_end = ~(UWORD16)((0x01C0 << (12 - rf.tx.guard_bits))) & 0xFFC0; // 3 tail bits
2463 // add tail bits to uplink data
2464 TM_ul_data[15] = (TM_ul_data[15] | gb_end) & tb_end;
2465 }
2466
2467 //===========================================
2468 // Insert the training sequence pattern .The location of TSC bits will
2469 // vary according to the value of guard bits used.
2470 //===========================================
2471 if ((pattern == 13)||(pattern==3))
2472 {
2473 // TM_ul_data[6] = (TM_ul_data[6] & 0xFE00) | ( (UWORD8) ((tsc[l1_config.tmode.tx_params.tsc]>>24) << 6 ) ); // tsc bits 1-2
2474 // TM_ul_data[7] = (TM_ul_data[7] & 0x0000) | ( (UWORD8) ((tsc[l1_config.tmode.tx_params.tsc]>>14) << 6 ) ); // tsc bits 3-12
2475 // TM_ul_data[8] = (TM_ul_data[8] & 0x0000) | ( (UWORD8) ((tsc[l1_config.tmode.tx_params.tsc]>>4 ) << 6 ) ); // tsc bits 13-22
2476 // TM_ul_data[9] = (TM_ul_data[9] & 0x07C0) | ( (UWORD8) ((tsc[l1_config.tmode.tx_params.tsc]>>0 ) << 12) ); // tsc bits 23-26
2477
2478 if (rf.tx.guard_bits <4) // TSC will be in [6],[7],[8]
2479 {
2480 tsc_bits_in_first_word = 9-rf.tx.guard_bits; // 7 bits when guard is 2, 6 bit when guard is 3
2481 tsc_front_mask = ((0xFFC0) << tsc_bits_in_first_word); // insert zeros from right
2482 //tsc_bits_in_last_word = 26 -10 -tsc_bits_in_first_word = (16-tsc_bits_in_first_word)
2483 tsc_end_mask = (((0xFFC0) >> (16-tsc_bits_in_first_word)) & 0xFFC0); //insert zeros from left
2484
2485 TM_ul_data[6] = (TM_ul_data[6] & tsc_front_mask)
2486 | ( ((UWORD16) ((tsc[l1_config.tmode.tx_params.tsc]>>(26-tsc_bits_in_first_word)) << 6 )) & (~tsc_front_mask) );
2487 TM_ul_data[7] = (TM_ul_data[7] & 0x0000)
2488 | ( ((UWORD16) ((tsc[l1_config.tmode.tx_params.tsc]<<(tsc_bits_in_first_word+6))>>16)) & (0xFFC0)); //next 10 bits of TSC
2489 TM_ul_data[8] = (TM_ul_data[8] & tsc_end_mask)
2490 | ( ((UWORD16) ((tsc[l1_config.tmode.tx_params.tsc] << (tsc_bits_in_first_word+6+10))>>16) )& (~tsc_end_mask));
2491 }
2492 else if ((rf.tx.guard_bits >=4) && (rf.tx.guard_bits <9) )// TSC will be in [6],[7],[8],[9]
2493 {
2494 tsc_bits_in_first_word = 9-rf.tx.guard_bits; // 5 bits when guard is 4, 1 bit when guard is 8
2495 tsc_front_mask = ((0xFFC0) << tsc_bits_in_first_word); // insert zeros from right
2496 //tsc_bits_in_last_word = 26 -10 -10 -tsc_bits_in_first_word = (6-tsc_bits_in_first_word)
2497 tsc_end_mask = (((0xFFC0) >> (6-tsc_bits_in_first_word)) & 0xFFC0); //insert zeros from left
2498
2499 TM_ul_data[6] = (TM_ul_data[6] & tsc_front_mask)
2500 | ( ((UWORD16) ((tsc[l1_config.tmode.tx_params.tsc]>>(26-tsc_bits_in_first_word)) << 6 )) & (~tsc_front_mask) );
2501 TM_ul_data[7] = (TM_ul_data[7] & 0x0000)
2502 | ( ((UWORD16) ((tsc[l1_config.tmode.tx_params.tsc]<<(tsc_bits_in_first_word+6))>>16)) & (0xFFC0) ); //next 10 bits of TSC
2503 TM_ul_data[8] = (TM_ul_data[8] & 0x0000)
2504 | ( ((UWORD16) ((tsc[l1_config.tmode.tx_params.tsc]<<(tsc_bits_in_first_word+6+10))>>16)) & (0xFFC0) ); //next 10 bits of TSC
2505 TM_ul_data[9] = (TM_ul_data[9] & tsc_end_mask)
2506 | ( ((UWORD16) ((tsc[l1_config.tmode.tx_params.tsc] << (tsc_bits_in_first_word+6+10+10))>>16) ) & (~tsc_end_mask));
2507 }
2508 else //(rf.tx.guard_bits>=9) : TSC will be in [7],[8],[9],
2509 {
2510 tsc_bits_in_first_word = 19-rf.tx.guard_bits; // 10 bits when guard is 9, 9 bits when guard is 10
2511 tsc_front_mask = ((0xFFC0) << tsc_bits_in_first_word); // insert zeros from right
2512 //tsc_bits_in_last_word = 26 -10 -tsc_bits_in_first_word = (16-tsc_bits_in_first_word)
2513 tsc_end_mask = (((0xFFC0) >> (16-tsc_bits_in_first_word)) & 0xFFC0); //insert zeros from left
2514
2515 TM_ul_data[7] = (TM_ul_data[7] & tsc_front_mask)
2516 | ( ((UWORD16) ((tsc[l1_config.tmode.tx_params.tsc]>>(26-tsc_bits_in_first_word)) << 6 )) & (~tsc_front_mask) );
2517 TM_ul_data[8] = (TM_ul_data[8] & 0x0000)
2518 | ( ((UWORD16) ((tsc[l1_config.tmode.tx_params.tsc]<<(tsc_bits_in_first_word+6))>>16)) & (0xFFC0) ); //next 10 bits of TSC
2519 TM_ul_data[9] = (TM_ul_data[9] & tsc_end_mask)
2520 | ( ((UWORD16) ((tsc[l1_config.tmode.tx_params.tsc] << (tsc_bits_in_first_word+6+10))>>16)) & (~tsc_end_mask));
2521 }
2522 }
2523
2524 // swap uplink data if IQ swap
2525 if(swap_flag)
2526 {
2527 for (i=0;i<=15;i++)
2528 {
2529 even_bits = TM_ul_data[i] & 0xAA80; // keep bits in even positions
2530 odd_bits = ~(TM_ul_data[i]) & 0x5540; // keep and complement bits in odd positions
2531 TM_ul_data[i] = even_bits | odd_bits; // swapped uplink data
2532 }
2533 }
2534 }
2535
2536
2537
2538 void l1a_tmode_send_ul_msg(T_TM_RETURN *tm_ret)
2539 {
2540 tm_transmit(tm_ret);
2541 }
2542
2543 /*******************************************************************************
2544 *
2545 * void tm_receive(void *inbuf, int size)
2546 *
2547 * Purpose : Parses TestMode data and copies it directly into TESTMODE_PRIM.
2548 * It forwards primitive to L1, except in the case of tm_init() which
2549 * gets executed in the CST.
2550 *
2551 * Arguments: In : command
2552 * Out:
2553 *
2554 * Returns : void
2555 *
2556 ******************************************************************************/
2557
2558 void tm_receive(UWORD8 *inbuf, UWORD16 size)
2559 {
2560 UWORD8 cksum, cid, error = 0;
2561 BOOL msg_used=FALSE;
2562
2563 #if (ETM_PROTOCOL == 1)
2564 UWORD8 mid = 0;
2565 #endif
2566
2567 UWORD8 *pmsg;
2568 xSignalHeaderRec *msg;
2569
2570 msg = os_alloc_sig(sizeof(T_TESTMODE_PRIM));
2571 msg->SignalCode = TESTMODE_PRIM;
2572
2573 // pmsg will be used to fill up the TestMode primitive with th
2574 // data, in consecutive order according to the definition of T_TESTMODE_PRIM.
2575 pmsg = (UWORD8 *)((T_TESTMODE_PRIM *)(msg->SigP));
2576
2577 #if (ETM_PROTOCOL == 1) // Use of ETM protocol
2578 #if (OP_L1_STANDALONE == 1)
2579 // Check MID
2580 *pmsg++ = mid = *inbuf++;
2581 if ((mid != ETM_RF) && (mid != ETM_CORE)) // check if coming from ETM RF or ETM CORE DLL
2582 error = -ETM_PACKET;
2583 #elif (OP_L1_STANDALONE == 0)
2584 *pmsg++ = mid = ETM_RF;
2585 #endif
2586
2587 // Copy CID/FID
2588 *pmsg++ = cid = *inbuf++;
2589 #if (OP_L1_STANDALONE == 1)
2590 // Copy data payload size (size minus MID byte and checksum byte)
2591 size -= 2;
2592 #endif
2593 *pmsg++ = --size; // Size of TM payload -1 for cid/fid
2594
2595 // Validate data payload size: check if longer than size of testmode
2596 // primitive minus cid, str_len_in_bytes, and two holes FIXME: This is a
2597 // really bad way of doing it!
2598 if (size > sizeof(T_TESTMODE_PRIM) - 4)
2599 error = -ETM_PACKET;
2600
2601 // The CID have been received. The data that follows are part of a
2602 // unique struct within the union of T_TESTMODE_PRIM, so we now
2603 // need to align at a 32-bit word boundary.
2604 *pmsg++ = 0;
2605
2606 // In a SSA integration the cksum is done in the etm_receive function
2607 #if (OP_L1_STANDALONE == 1)
2608 if (!error)
2609 {
2610 cksum = mid;
2611 cksum ^= cid;
2612
2613 while (size--)
2614 {
2615 cksum ^= *inbuf;
2616 *pmsg++ = *inbuf++;
2617 }
2618 if (cksum != *inbuf)
2619 error = -ETM_PACKET;
2620 }
2621 #elif (OP_L1_STANDALONE == 0)
2622 // Copy payload without cid/fid
2623 while (size--)
2624 {
2625 *pmsg++ = *inbuf++;
2626 }
2627 #endif
2628
2629 // At this point, all the data have been parsed and copied into
2630 // the TestMode primitive. Now we send the primitive to L1.
2631 if (!error)
2632 {
2633 os_send_sig(msg, L1C1_QUEUE);
2634 msg_used=TRUE;
2635 }
2636 else
2637 {
2638 UWORD8 mymsg[4];
2639
2640 // on error, return short error message; cid, error, checksum
2641 mymsg[0] = mid;
2642 mymsg[1] = cid; // the payload fid
2643 mymsg[2] = error; // status
2644 mymsg[3] = cid ^ error; // checksum
2645
2646 #if (TRACE_TYPE==0) || (TRACE_TYPE==1) || (TRACE_TYPE==4) || (TRACE_TYPE==7)
2647 rvt_send_trace_cpy((T_RVT_BUFFER) mymsg,
2648 tm_trace_user_id,
2649 4,
2650 RVT_BINARY_FORMAT);
2651 #endif
2652 }
2653
2654 #else // end of (ETM_PROTOCOL ==1)
2655
2656 // Copy CID
2657 *pmsg++ = cid = *inbuf++;
2658 // Copy data payload size (size minus CID byte and checksum byte)
2659 size -= 2;
2660 *pmsg++ = size;
2661
2662 // Validate data payload size: check if longer than size of testmode
2663 // primitive minus cid, str_len_in_bytes, and two holes FIXME: This is a
2664 // really bad way of doing it!
2665 if (size > sizeof(T_TESTMODE_PRIM) - 4)
2666 error = E_PACKET;
2667
2668 // The CID have been received. The data that follows are part of a
2669 // unique struct within the union of T_TESTMODE_PRIM, so we now
2670 // need to align at a 32-bit word boundary.
2671 pmsg += 2;
2672
2673 if (!error)
2674 {
2675 cksum = cid;
2676 while (size--)
2677 {
2678 cksum ^= *inbuf;
2679 *pmsg++ = *inbuf++;
2680 }
2681 if (cksum != *inbuf)
2682 error = E_CHECKSUM;
2683 }
2684
2685 // At this point, all the data have been parsed and copied into
2686 // the TestMode primitive. Now we send the primitive to L1.
2687 if (!error)
2688 {
2689 os_send_sig(msg, L1C1_QUEUE);
2690 msg_used=TRUE;
2691 }
2692 else
2693 {
2694 UWORD8 mymsg[3];
2695 // on error, return short error message; error, cid/fid, checksum
2696 mymsg[0] = cid;
2697 mymsg[1] = error;
2698 mymsg[2] = cid ^ error; // checksum
2699
2700 #if (TRACE_TYPE==1) || (TRACE_TYPE==4) || (TRACE_TYPE==7) || (TRACE_TYPE==0)
2701 rvt_send_trace_cpy((T_RVT_BUFFER) mymsg, tm_trace_user_id,3, RVT_BINARY_FORMAT);
2702 #endif
2703 }
2704
2705 #endif // end of (ETM_PROTOCOL ==0)
2706
2707 // if the message allocated is not sent to L1A, it has to be deallocated
2708 if(msg_used==FALSE)
2709 os_free_sig(msg);
2710 }
2711
2712 void tm_transmit(T_TM_RETURN *tm_ret)
2713 {
2714 UWORD8 size, cksum;
2715 UWORD8 *pbuf, *ptmret;
2716 UWORD8 buf[TM_PAYLOAD_UPLINK_SIZE_MAX + TM_UPLINK_PACKET_OVERHEAD];
2717
2718 pbuf = &buf[0];
2719
2720 // move the header
2721 #if (ETM_PROTOCOL == 1)
2722 *pbuf++ = tm_ret->mid;
2723 cksum = tm_ret->mid;
2724 *pbuf++ = tm_ret->status;
2725 cksum ^= tm_ret->status;
2726 *pbuf++ = tm_ret->cid;
2727 cksum ^= tm_ret->cid;
2728
2729 // Include index if not equal to zero, and if not an error
2730 // Exception: in TX_TEMPLATE_READ we always include the index.
2731 if ((tm_ret->status == -ETM_OK) &&
2732 (tm_ret->index || tm_ret->cid == TX_TEMPLATE_READ)){
2733 *pbuf++ = tm_ret->index;
2734 cksum ^= tm_ret->index;
2735 }
2736
2737 #else
2738 *pbuf++ = tm_ret->cid;
2739 *pbuf++ = tm_ret->status;
2740 cksum = tm_ret->cid ^ tm_ret->status;
2741
2742 // Include index if not equal to zero, and if not an error
2743 // Exception: in TX_TEMPLATE_READ we always include the index.
2744 if ((tm_ret->status == E_OK) &&
2745 (tm_ret->index || tm_ret->cid == TX_TEMPLATE_READ)){
2746 *pbuf++ = tm_ret->index;
2747 cksum ^= tm_ret->index;
2748 }
2749 #endif
2750
2751 ptmret = (UWORD8 *) &tm_ret->result[0];
2752 size = tm_ret->size;
2753 while (size--) {
2754 *pbuf++ = *ptmret;
2755 cksum ^= *ptmret++;
2756 }
2757
2758 // move the checksum and append it to buf
2759 *pbuf++ = cksum;
2760
2761 #if (TRACE_TYPE==1) || (TRACE_TYPE==4) || (TRACE_TYPE==7) || (TRACE_TYPE==0)
2762 rvt_send_trace_cpy(buf, tm_trace_user_id, pbuf - buf, RVT_BINARY_FORMAT);
2763 #endif
2764 }
2765
2766
2767 #if ((L1_STEREOPATH == 1) && (CODE_VERSION == NOT_SIMULATION) && (OP_L1_STANDALONE == 1))
2768 /*******************************************************************************
2769 *
2770 * UWORD16 l1tm_stereopath_get_pattern(UWORD16 sampling_freq, UWORD16 sin_freq_left,UWORD16 sin_freq_right, UWORD8 data_type)
2771 *
2772 * Purpose : this function is use to get a complete period of a sinusoide depending on
2773 * the sinusoide freq (L+R), the sampling freq and the type of samples (S8,S16,S32)
2774 *
2775 * Arguments: sampling_freq : sampling frequency
2776 * sin_freq_left : frequency of the left channel sinusoide
2777 * sin_freq_right : frequency of the right channel sinusoide
2778 * data_type : type of samples
2779 *
2780 * Returns : number of elements in the pattern
2781 *
2782 ******************************************************************************/
2783
2784 UWORD16 l1tm_stereopath_get_pattern(UWORD16 sampling_freq, UWORD16 sin_freq_left,UWORD16 sin_freq_right, UWORD8 data_type)
2785 {
2786 float max_sin_period;
2787 float my_time;
2788 UWORD16 i;
2789
2790 // get the lowest frequency to get the biggest period
2791 if (sin_freq_left > sin_freq_right)
2792 {
2793 max_sin_period = 1 / (float) sin_freq_right;
2794 }
2795 else
2796 {
2797 max_sin_period = 1 / (float) sin_freq_left;
2798 }
2799
2800 my_time = 0;
2801 i = 0;
2802
2803 if (data_type == AUDIO_SP_DATA_S8)
2804 {
2805 WORD8* my_ptr;
2806
2807 // cast the steropath_pattern to a pointer on 8 bits samples
2808 my_ptr = (WORD8*) l1tm.stereopath.stereopath_pattern;
2809
2810 // fill the pattern while the biggest period is not reached
2811 while (my_time < max_sin_period)
2812 {
2813 my_ptr[i++] = 0x7F * sin(2*3.1416*my_time*sin_freq_left);
2814 my_ptr[i++] = 0x7F * sin(2*3.1416*my_time*sin_freq_right);
2815
2816 my_time = i/2/((float) sampling_freq);
2817 }
2818 }
2819 else // S16
2820 {
2821 WORD16* my_ptr;
2822
2823 // cast the steropath_pattern to a pointer on 16 bits samples
2824 my_ptr = (WORD16*) l1tm.stereopath.stereopath_pattern;
2825
2826 // fill the pattern while the biggest period is not reached
2827 while (my_time < max_sin_period)
2828 {
2829 my_ptr[i++] = 0x7FFF * sin(2*3.1416*my_time*sin_freq_left);
2830 my_ptr[i++] = 0x7FFF * sin(2*3.1416*my_time*sin_freq_right);
2831
2832 my_time = i/2/((float) sampling_freq);
2833 }
2834
2835 }
2836
2837 return (i);
2838
2839 }
2840
2841 /*******************************************************************************
2842 *
2843 * void l1tm_stereopath_fill_buffer(void* buffer_address)
2844 *
2845 * Purpose : this function is use to fill a buffer with a predefined pattern
2846 *
2847 * Arguments: buffer_address : address of the buffer to fill
2848 *
2849 * Returns : none
2850 *
2851 ******************************************************************************/
2852
2853 void l1tm_stereopath_fill_buffer(void* buffer_address)
2854 {
2855 static UWORD16 my_counter = 0;
2856 UWORD16 copied_samples;
2857
2858 UWORD16 i;
2859
2860
2861 if (l1a_l1s_com.stereopath_drv_task.parameters.data_type == AUDIO_SP_DATA_S8)
2862 {
2863 WORD8* start_address;
2864 WORD8* my_ptr;
2865
2866 // l1tm.stereopath.stereopath_buffer_number is a variable used to know which half of the buffer we have to fill
2867 if (l1tm.stereopath.stereopath_buffer_number == 0)
2868 {
2869 // first half
2870 start_address = (WORD8*) buffer_address;
2871 l1tm.stereopath.stereopath_buffer_number = 1;
2872 }
2873 else
2874 {
2875 // second half, add the frame number to get the half buffer address
2876 start_address = ((WORD8*) buffer_address) + l1a_l1s_com.stereopath_drv_task.parameters.frame_number;
2877 l1tm.stereopath.stereopath_buffer_number = 0;
2878 }
2879
2880 // copied_samples is the number of samples copied to the half buffer
2881 copied_samples = 0;
2882 // cast the steropath_pattern to a pointer on 8 bits samples
2883 my_ptr = (WORD8*) l1tm.stereopath.stereopath_pattern;
2884
2885 if (l1a_l1s_com.stereopath_drv_task.parameters.frame_number > l1tm.stereopath.stereopath_nb_samples)
2886 {
2887 // size of the half buffer to fill is bigger than the predefined pattern
2888 // start to fill the buffer with the end of the not complete previous pattern (from current_sample to the last one)
2889 memcpy(start_address,my_ptr+l1tm.stereopath.stereopath_current_sample,l1tm.stereopath.stereopath_nb_samples-l1tm.stereopath.stereopath_current_sample);
2890 copied_samples = l1tm.stereopath.stereopath_nb_samples-l1tm.stereopath.stereopath_current_sample;
2891
2892 // while there is still enough place in the buffer to copy a complete pattern ...
2893 while (copied_samples<l1a_l1s_com.stereopath_drv_task.parameters.frame_number-l1tm.stereopath.stereopath_nb_samples)
2894 {
2895 // ... copy a complete pattern
2896 memcpy(start_address+copied_samples,my_ptr,l1tm.stereopath.stereopath_nb_samples);
2897 copied_samples += l1tm.stereopath.stereopath_nb_samples;
2898 }
2899
2900 // fill the rest of the buffer with a part of the pattern
2901 memcpy(start_address+copied_samples,my_ptr,l1a_l1s_com.stereopath_drv_task.parameters.frame_number-copied_samples);
2902 // save the last pattern sample copied in the buffer for next time (to get a continuous sound)
2903 l1tm.stereopath.stereopath_current_sample = l1a_l1s_com.stereopath_drv_task.parameters.frame_number-copied_samples;
2904
2905 }
2906 else
2907 {
2908 // size of the half buffer to fill is smaller than the predefined pattern
2909 // fill the buffer with a part of the pattern
2910 memcpy(start_address,my_ptr+l1tm.stereopath.stereopath_current_sample,l1a_l1s_com.stereopath_drv_task.parameters.frame_number);
2911 // save the last pattern sample copied in the buffer for next time (to get a continuous sound)
2912 l1tm.stereopath.stereopath_current_sample += l1a_l1s_com.stereopath_drv_task.parameters.frame_number;
2913
2914 if (l1tm.stereopath.stereopath_current_sample > l1tm.stereopath.stereopath_nb_samples)
2915 {
2916 l1tm.stereopath.stereopath_current_sample -= l1tm.stereopath.stereopath_nb_samples;
2917 }
2918 }
2919 }
2920 else // S16
2921 {
2922 WORD16* start_address;
2923 WORD16* my_ptr;
2924
2925 // l1tm.stereopath.stereopath_buffer_number is a variable used to know which half of the buffer we have to fill
2926 if (l1tm.stereopath.stereopath_buffer_number == 0)
2927 {
2928 // first half
2929 start_address = (WORD16*) buffer_address;
2930 l1tm.stereopath.stereopath_buffer_number = 1;
2931 }
2932 else
2933 {
2934 // second half, add the frame number to get the half buffer address
2935 start_address = ((WORD16*) buffer_address) + l1a_l1s_com.stereopath_drv_task.parameters.frame_number;
2936 l1tm.stereopath.stereopath_buffer_number = 0;
2937 }
2938
2939 // copied_samples is the number of samples copied to the half buffer
2940 copied_samples = 0;
2941 // cast the steropath_pattern to a pointer on 16 bits samples
2942 my_ptr = (WORD16*) l1tm.stereopath.stereopath_pattern;
2943
2944 if (l1a_l1s_com.stereopath_drv_task.parameters.frame_number > l1tm.stereopath.stereopath_nb_samples)
2945 {
2946 // size of the half buffer to fill is bigger than the predefined pattern
2947 // start to fill the buffer with the end of the not complete previous pattern (from current_sample to the last one)
2948 memcpy(start_address, my_ptr+l1tm.stereopath.stereopath_current_sample,(l1tm.stereopath.stereopath_nb_samples-l1tm.stereopath.stereopath_current_sample)*2);
2949 copied_samples = l1tm.stereopath.stereopath_nb_samples-l1tm.stereopath.stereopath_current_sample;
2950
2951 // while there is still enough place in the buffer to copy a complete pattern ...
2952 while (copied_samples<l1a_l1s_com.stereopath_drv_task.parameters.frame_number-l1tm.stereopath.stereopath_nb_samples)
2953 {
2954 // ... copy a complete pattern
2955 memcpy(start_address+copied_samples,my_ptr,l1tm.stereopath.stereopath_nb_samples*2);
2956 copied_samples += l1tm.stereopath.stereopath_nb_samples;
2957 }
2958
2959 // fill the rest of the buffer with a part of the pattern
2960 memcpy(start_address+copied_samples,my_ptr,(l1a_l1s_com.stereopath_drv_task.parameters.frame_number-copied_samples)*2);
2961 // save the last pattern sample copied in the buffer for next time (to get a continuous sound)
2962 l1tm.stereopath.stereopath_current_sample = l1a_l1s_com.stereopath_drv_task.parameters.frame_number-copied_samples;
2963
2964 }
2965 else
2966 {
2967 // size of the half buffer to fill is smaller than the predefined pattern
2968 // fill the buffer with a part of the pattern
2969 memcpy(start_address,my_ptr+l1tm.stereopath.stereopath_current_sample,l1a_l1s_com.stereopath_drv_task.parameters.frame_number);
2970 l1tm.stereopath.stereopath_current_sample += l1a_l1s_com.stereopath_drv_task.parameters.frame_number;
2971
2972 // save the last pattern sample copied in the buffer for next time (to get a continuous sound)
2973 if (l1tm.stereopath.stereopath_current_sample > l1tm.stereopath.stereopath_nb_samples)
2974 {
2975 l1tm.stereopath.stereopath_current_sample -= l1tm.stereopath.stereopath_nb_samples;
2976 }
2977
2978 }
2979 }
2980 }
2981
2982 /*******************************************************************************
2983 *
2984 * void l1tm_stereopath_DMA_handler(SYS_UWORD16 dma_status)
2985 *
2986 * Purpose : this function is the stereopath DMA interrupt handler
2987 *
2988 * Arguments: dma_status : type of interrupt
2989 *
2990 * Returns : none
2991 *
2992 ******************************************************************************/
2993 void l1tm_stereopath_DMA_handler(SYS_UWORD16 dma_status)
2994 {
2995 // stereopath DMA handler, check which type of interrupt it is
2996 if (F_DMA_COMPARE_CHANNEL_IT_STATUS_BLOCK(dma_status))
2997 {
2998 l1tm.stereopath.stereopath_block++;
2999 // Block --> fill a new buffer
3000 l1tm_stereopath_fill_buffer((void*) l1a_l1s_com.stereopath_drv_task.parameters.source_buffer_address);
3001 }
3002 if (F_DMA_COMPARE_CHANNEL_IT_STATUS_HALF_BLOCK(dma_status))
3003 {
3004 l1tm.stereopath.stereopath_half_block++;
3005 // Half Block --> fill a new buffer
3006 l1tm_stereopath_fill_buffer((void*) l1a_l1s_com.stereopath_drv_task.parameters.source_buffer_address);
3007 }
3008 if (F_DMA_COMPARE_CHANNEL_IT_STATUS_TIME_OUT_SRC(dma_status))
3009 l1tm.stereopath.stereopath_source_timeout++;
3010 if (F_DMA_COMPARE_CHANNEL_IT_STATUS_TIME_OUT_DST(dma_status))
3011 l1tm.stereopath.stereopath_dest_timeout++;
3012 if (F_DMA_COMPARE_CHANNEL_IT_STATUS_DROP(dma_status))
3013 l1tm.stereopath.stereopath_drop++;
3014 if (F_DMA_COMPARE_CHANNEL_IT_STATUS_FRAME(dma_status))
3015 l1tm.stereopath.stereopath_frame++;
3016 }
3017 #endif
3018
3019
3020
3021 #if (CODE_VERSION != SIMULATION)
3022 void l1tm_tpu_table_write(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
3023 {
3024 Cust_tm_tpu_table_write(tm_return,
3025 prim->u.tm_table.index,
3026 prim->str_len_in_bytes - 1, // subtract 8-bit index
3027 prim->u.tm_table.table);
3028 }
3029
3030 void l1tm_tpu_table_read(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return)
3031 {
3032 Cust_tm_tpu_table_read(tm_return, prim->u.tm_table.index);
3033 }
3034 #endif // (CODE_VERSION != SIMULATION)
3035
3036
3037 /*------------------------------------------------------------------*/
3038 /* l1tm_PRBS1_generate() */
3039 /*------------------------------------------------------------------*/
3040 /* */
3041 /* Parameters : UWORD16 *TM_ul_data */
3042 /* ------------- */
3043 /* point to the uplink burts table to be filled */
3044 /* with the PRBS 1 of bits */
3045 /* */
3046 /* Return : Void */
3047 /* ------------- */
3048 /* */
3049 /* Description : */
3050 /* ------------- */
3051 /* This algorithm generates a Pseudo Random Bit Sequence */
3052 /* using a method called method "Primitive Polynomial Modulo 2" */
3053 /* For a sequence length of (2^15-1) we a polynomial of order 15 */
3054 /* is used, the coefficients are [ 15, 1, 0 ] */
3055 /* The basic idea is to generate the new bit by XORing all the */
3056 /* coefficients of the polynomial except coeff 0 */
3057 /* i.e newbit = ( B15 XOR B1 ) */
3058 /* The following notation must be used for the bit numbering: */
3059 /* _______________________________________________________ */
3060 /*|B16|B15|B14|B13|B12|B11|B10|B9|B8|B7|B6|B5|B4|B3|B2|B1| */
3061 /*------------------------------------------------------------------*/
3062 /* */
3063 /* each word of the uplink buffer needs to be filled by new 10 bits */
3064 /*------------------------------------------------------------------*/
3065 void l1tm_PRBS1_generate(UWORD16 *TM_ul_data)
3066 {
3067 #define B15_MASK 0x4000
3068 #define B1_MASK 0x0001
3069 #define MASK_16BITS 0xFFFF
3070
3071 UWORD16 newbit =0x0000;
3072 UWORD8 index ,word;
3073
3074 //generate 16 words to fill Uplink table
3075 for (word=0;word<16;word++)
3076 {
3077 // generate new 10 bits from the sequence
3078 for (index =0; index< 10;index++)
3079 {
3080 // generate new bit , using the "Primitive Polynomial Modulo 2 " method with coeff. ( 15, 1, 0 )
3081 //XOR bit 15 with bit 1.
3082 newbit = (((l1tm.tmode_prbs.prbs1_seed& B15_MASK)>>14)^(l1tm.tmode_prbs.prbs1_seed & B1_MASK));
3083 // insert new bit in the sequence.
3084 l1tm.tmode_prbs.prbs1_seed = (l1tm.tmode_prbs.prbs1_seed << 1) | newbit;
3085 }
3086 TM_ul_data[word]=(UWORD16)((l1tm.tmode_prbs.prbs1_seed&MASK_16BITS)<<6);
3087 }
3088 }
3089
3090 #endif // TESTMODE
3091
3092