comparison src/cs/layer1/tm_cust0/l1tm_cust.c @ 0:b6a5e36de839

src/cs: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:39:26 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:b6a5e36de839
1 /************* Revision Controle System Header *************
2 * GSM Layer 1 software
3 * L1TM_CUST.C
4 *
5 * Filename %M%
6 * Version %I%
7 * Date %G%
8 *
9 ************* Revision Controle System Header *************/
10
11 #include "l1_confg.h"
12 #if TESTMODE
13
14 #include "tm_defs.h"
15 #include "l1_const.h"
16 #include "l1_types.h"
17
18 #include "l1tm_defty.h"
19 #include "l1tm_cust.h"
20
21 #if (AUDIO_TASK == 1)
22 #include "l1audio_const.h"
23 #include "l1audio_cust.h"
24 #include "l1audio_defty.h"
25 #endif
26
27 #if (L1_GTT == 1)
28 #include "l1gtt_const.h"
29 #include "l1gtt_defty.h"
30 #endif
31 #include "l1_defty.h"
32 #include "l1_msgty.h"
33 #include "l1_tabs.h"
34
35 #include "l1tm_msgty.h"
36 #include "l1tm_varex.h"
37
38 #include "abb.h"
39
40 #if (RF==35)
41 #include "tpudrv35.h"
42 #include "l1_rf35.h"
43 #endif
44
45 #if (RF==12)
46 #include "tpudrv12.h"
47 #include "l1_rf12.h"
48 #endif
49
50 #if (RF==10)
51 #include "tpudrv10.h"
52 #include "l1_rf10.h"
53 #endif
54
55 #if (RF==8)
56 #include "tpudrv8.h"
57 #include "l1_rf8.h"
58 #endif
59
60 #if (RF==2)
61 #include "l1_rf2.h"
62 #endif
63
64 #include <string.h>
65
66 // Import band configuration from Flash module (need to replace by an access function)
67 //extern UWORD8 std;
68 extern T_L1_CONFIG l1_config;
69 extern T_RF rf;
70 extern T_RF_BAND rf_band[GSM_BANDS];
71 extern UWORD16 AGC_TABLE[AGC_TABLE_SIZE];
72 extern T_ADC adc;
73 extern T_ADCCAL adc_cal;
74 extern UWORD16 TM_ul_data[16]; //Uplink data to be stored into ABB Uplink buffer
75 extern T_STD_CONFIG std_config[];
76 static UWORD8 tm_band = 0;
77
78 // External function prototypes
79 void get_cal_from_nvmem (UWORD8 *ptr, UWORD16 len, UWORD8 id);
80 UWORD8 save_cal_in_nvmem (UWORD8 *ptr, UWORD16 len, UWORD8 id);
81 void Cust_init_std(void);
82 void l1_tpu_init_light(void);
83
84 enum {
85 TM_RF_ID = 0,
86 TM_ADC_ID = 1
87 };
88
89 typedef signed char effs_t;
90 // external FFS function prototypes
91 effs_t ffs_mkdir(const char *pathname);
92 void config_ffs_write(char type);
93
94 /***********************************************************************/
95 /* TESTMODE 4.X */
96 /***********************************************************************/
97
98
99 /*----------------------------------------------------------*/
100 /* Cust_tm_init() */
101 /*----------------------------------------------------------*/
102 /* Parameters : */
103 /* Return : */
104 /* Functionality : Init default configuration for TM params */
105 /*----------------------------------------------------------*/
106
107 void Cust_tm_init(void)
108 {
109 UWORD32 i;
110
111 l1_config.adc_enable = ADC_ENABLE; // ADC readings enabled
112 l1_config.agc_enable = AGC_ENABLE; // AGC algo enabled
113 l1_config.afc_enable = AFC_ENABLE; // AFC algo enabled
114 l1_config.tmode.rf_params.bcch_arfcn = TM_BCCH_ARFCN;
115 l1_config.tmode.rf_params.tch_arfcn = TM_TCH_ARFCN;
116 l1_config.tmode.rf_params.mon_arfcn = TM_MON_ARFCN;
117 l1_config.tmode.rf_params.channel_type = TM_CHAN_TYPE; // TCH_F
118 l1_config.tmode.rf_params.subchannel = TM_SUB_CHAN;
119 l1_config.tmode.rf_params.reload_ramps_flag = 0;
120 l1_config.tmode.rf_params.tmode_continuous = TM_NO_CONTINUOUS;
121 l1_config.tmode.rx_params.slot_num = TM_SLOT_NUM; // Time Slot
122 l1_config.tmode.rx_params.agc = TM_AGC_VALUE; //This may be outside the range of the RF chip used
123 l1_config.tmode.rx_params.pm_enable = TM_PM_ENABLE;
124 l1_config.tmode.rx_params.lna_off = TM_LNA_OFF;
125 l1_config.tmode.rx_params.number_of_measurements = TM_NUM_MEAS;
126 l1_config.tmode.rx_params.place_of_measurement = TM_WIN_MEAS;
127 l1_config.tmode.tx_params.txpwr = TM_TXPWR; // Min power level for GSM900
128 l1_config.tmode.tx_params.txpwr_skip = TM_TXPWR_SKIP;
129 l1_config.tmode.tx_params.timing_advance = TM_TA;
130 l1_config.tmode.tx_params.burst_type = TM_BURST_TYPE; // default is normal up-link burst
131 l1_config.tmode.tx_params.burst_data = TM_BURST_DATA; // default is all zeros
132 l1_config.tmode.tx_params.tsc = TM_TSC; // Training Sequence ("BCC" on BSS)
133 #if (CODE_VERSION != SIMULATION)
134 l1_config.tmode.stats_config.num_loops = TM_NUM_LOOPS; // 0 actually means infinite
135 #else
136 l1_config.tmode.stats_config.num_loops = 4; // 0 actually means infinite
137 #endif
138 l1_config.tmode.stats_config.auto_result_loops = TM_AUTO_RESULT_LOOPS; // 0 actually means infinite
139 l1_config.tmode.stats_config.auto_reset_loops = TM_AUTO_RESET_LOOPS; // 0 actually means infinite
140 l1_config.tmode.stats_config.stat_type = TM_STAT_TYPE;
141 l1_config.tmode.stats_config.stat_bitmask = TM_STAT_BITMASK;
142
143 #if (CODE_VERSION != SIMULATION)
144 // Initialize APCDEL1 register of Omega
145 ABB_Write_Register_on_page(PAGE0, APCDEL1, (C_APCDEL1 - 0x0004) >> 6);
146 #endif
147
148 l1tm.tm_msg_received = FALSE;
149
150 for (i=0;i<16;i++)
151 TM_ul_data[i]=0;
152
153 #if L1_GPRS
154 l1_config.tmode.rf_params.pdtch_arfcn = TM_PDTCH_ARFCN;
155 l1_config.tmode.rf_params.multislot_class = TM_MULTISLOT_CLASS;
156 l1_config.tmode.stats_config.stat_gprs_slots = TM_STAT_GPRS_SLOTS;
157 l1_config.tmode.rx_params.timeslot_alloc = TM_RX_ALLOCATION;
158 l1_config.tmode.rx_params.coding_scheme = TM_RX_CODING_SCHEME;
159 l1_config.tmode.tx_params.timeslot_alloc = TM_TX_ALLOCATION;
160 l1_config.tmode.tx_params.coding_scheme = TM_TX_CODING_SCHEME;
161 for (i=0; i<8; i++)
162 l1_config.tmode.tx_params.txpwr_gprs[i] = TM_TXPWR_GPRS;
163
164 for (i=0; i<27; i++)
165 l1_config.tmode.tx_params.rlc_buffer[i] = 0;
166 #endif
167 }
168
169
170 /**********************************************************************/
171 /* Test mode functions used for RF calibration */
172 /**********************************************************************/
173
174 void Cust_tm_rf_param_write(T_TM_RETURN *tm_return, WORD16 index, UWORD16 value)
175 {
176 switch (index)
177 {
178 case STD_BAND_FLAG:
179 {
180 UWORD8 std_temp, band_temp;
181
182 std_temp = value & 0xff; // tm_band = b7..0 of value
183 band_temp = value >> 8; // band = b15..8 of value
184 // get define
185 //if (sizeof(std_config)/sizeof(T_STD_CONFIG) <= std_temp)
186 if (9 <= std_temp) // std max
187 {
188 tm_return->status = E_BADINDEX;
189 break;
190 }
191 else if ( GSM_BANDS <= band_temp)
192 {
193 tm_return->status = E_BADINDEX;
194 break;
195 }
196 else if ( BAND_NONE == std_config[std_temp].band[band_temp])
197 {
198 tm_return->status = E_BADINDEX;
199 break;
200 }
201 else
202 {
203 l1_config.std.id = std_temp;
204 tm_band = band_temp;
205 // update RAM struct with either default or ffs
206 Cust_init_std();
207 l1_tpu_init_light();
208 tm_return->status = E_OK;
209 break;
210 }
211 }
212
213 case INITIAL_AFC_DAC:
214 {
215 rf.afc.eeprom_afc = (WORD16) value << 3; // shift to put into F13.3 format
216 l1_config.params.eeprom_afc = rf.afc.eeprom_afc;
217
218 tm_return->status = E_OK;
219 break;
220 }
221 default:
222 {
223 tm_return->status = E_BADINDEX;
224 break;
225 }
226 } // end switch
227 }
228
229 void Cust_tm_rf_param_read(T_TM_RETURN *tm_return, WORD16 index)
230 {
231 volatile UWORD16 value;
232
233 switch (index)
234 {
235 case STD_BAND_FLAG:
236 {
237 value = ((tm_band << 8) | (l1_config.std.id) ); // return global std, tm_band (intel format)
238 break;
239 }
240 case INITIAL_AFC_DAC:
241 {
242 value = rf.afc.eeprom_afc >> 3; // returned as F13.3
243 break;
244 }
245 default:
246 {
247 tm_return->size = 0;
248 tm_return->status = E_BADINDEX;
249 return;
250 }
251 } // end switch
252
253 memcpy(tm_return->result, (UWORD8 *)&value, 2);
254 tm_return->size = 2;
255 tm_return->status = E_OK;
256 }
257
258 void Cust_tm_rf_table_write(T_TM_RETURN *tm_return, WORD8 index, UWORD8 size, UWORD8 table[])
259 {
260 UWORD8 band=0;
261
262 tm_return->index = index; // store index before it gets modified
263 tm_return->size = 0;
264
265 switch (index)
266 {
267 case RX_AGC_TABLE:
268 {
269 if (size != sizeof(AGC_TABLE))
270 {
271 tm_return->status = E_BADSIZE;
272 break;
273 }
274
275 memcpy(&AGC_TABLE[0], table, size);
276 tm_return->status = E_OK;
277 break;
278 }
279 case AFC_PARAMS:
280 {
281
282 #if (VCXO_ALGO == 1)
283 if (size != 24) // 4 UWORD32 + 4 WORD16 values
284 #else
285 if (size != 16) // 4 UWORD32 values
286 #endif
287 {
288 tm_return->status = E_BADSIZE;
289 break;
290 }
291
292 memcpy(&rf.afc.psi_sta_inv, table, size);
293 l1_config.params.psi_sta_inv = rf.afc.psi_sta_inv;
294 l1_config.params.psi_st = rf.afc.psi_st;
295 l1_config.params.psi_st_32 = rf.afc.psi_st_32;
296 l1_config.params.psi_st_inv = rf.afc.psi_st_inv;
297
298 #if (CODE_VERSION == NOT_SIMULATION)
299 #if (VCXO_ALGO == 1)
300 l1_config.params.afc_dac_center = rf.afc.dac_center;
301 l1_config.params.afc_dac_min = rf.afc.dac_min;
302 l1_config.params.afc_dac_max = rf.afc.dac_max;
303 l1_config.params.afc_snr_thr = rf.afc.snr_thr;
304 #endif
305 #endif
306
307 tm_return->status = E_OK;
308 break;
309 }
310 case RX_AGC_GLOBAL_PARAMS:
311 {
312 if (size != 8) // 4 UWORD16 values
313 {
314 tm_return->status = E_BADSIZE;
315 break;
316 }
317
318 memcpy(&rf.rx.agc.low_agc_noise_thr, table, size);
319 l1_config.params.low_agc_noise_thr = rf.rx.agc.low_agc_noise_thr;
320 l1_config.params.high_agc_sat_thr = rf.rx.agc.high_agc_sat_thr;
321 l1_config.params.low_agc = rf.rx.agc.low_agc;
322 l1_config.params.high_agc = rf.rx.agc.high_agc;
323
324 tm_return->status = E_OK;
325 break;
326 }
327 case RX_IL_2_AGC_MAX:
328 {
329 if (size != sizeof(rf.rx.agc.il2agc_max))
330 {
331 tm_return->status = E_BADSIZE;
332 break;
333 }
334
335 memcpy(&rf.rx.agc.il2agc_max[0], table, size);
336 tm_return->status = E_OK;
337 break;
338 }
339 case RX_IL_2_AGC_PWR:
340 {
341 if (size != sizeof(rf.rx.agc.il2agc_pwr))
342 {
343 tm_return->status = E_BADSIZE;
344 break;
345 }
346
347 memcpy(&rf.rx.agc.il2agc_pwr[0], table, size);
348 tm_return->status = E_OK;
349 break;
350 }
351 case RX_IL_2_AGC_AV:
352 {
353 if (size != sizeof(rf.rx.agc.il2agc_av))
354 {
355 tm_return->status = E_BADSIZE;
356 break;
357 }
358
359 memcpy(&rf.rx.agc.il2agc_av[0], table, size);
360 tm_return->status = E_OK;
361 break;
362 }
363 case TX_LEVELS:
364 {
365 if (size != sizeof(rf_band[tm_band].tx.levels))
366 {
367 tm_return->status = E_BADSIZE;
368 break;
369 }
370
371 memcpy(&rf_band[tm_band].tx.levels[0], table, size);
372 tm_return->status = E_OK;
373 break;
374 }
375 case TX_CAL_CHAN: // generic for all bands
376 {
377 if (size != sizeof(rf_band[tm_band].tx.chan_cal_table))
378 {
379 tm_return->status = E_BADSIZE;
380 break;
381 }
382
383 memcpy(&rf_band[tm_band].tx.chan_cal_table[0][0], table, size);
384 tm_return->status = E_OK;
385 break;
386 }
387 case TX_CAL_TEMP: // generic for all bands
388 {
389 if (size != sizeof(rf_band[tm_band].tx.temp))
390 {
391 tm_return->status = E_BADSIZE;
392 break;
393 }
394
395 memcpy(&rf_band[tm_band].tx.temp[0], table, size);
396 tm_return->status = E_OK;
397 break;
398 }
399 case RX_CAL_CHAN: // generic for all bands
400 {
401 if (size != sizeof(rf_band[tm_band].rx.agc_bands))
402 {
403 tm_return->status = E_BADSIZE;
404 break;
405 }
406
407 memcpy(&rf_band[tm_band].rx.agc_bands[0], table, size);
408 tm_return->status = E_OK;
409 break;
410 }
411 case RX_CAL_TEMP: // generic for all bands
412 {
413 if (size != sizeof(rf_band[tm_band].rx.temp))
414 {
415 tm_return->status = E_BADSIZE;
416 break;
417 }
418
419 memcpy(&rf_band[tm_band].rx.temp[0], table, size);
420 tm_return->status = E_OK;
421 break;
422 }
423 case RX_AGC_PARAMS:
424 {
425 if (size != sizeof(rf_band[tm_band].rx.rx_cal_params))
426 {
427 tm_return->status = E_BADSIZE;
428 break;
429 }
430
431 memcpy(&rf_band[tm_band].rx.rx_cal_params, table, size);
432 if (tm_band == 0)
433 {
434 l1_config.std.g_magic_band1 = rf_band[tm_band].rx.rx_cal_params.g_magic;
435 l1_config.std.lna_att_band1 = rf_band[tm_band].rx.rx_cal_params.lna_att;
436 l1_config.std.lna_switch_thr_low_band1 = rf_band[tm_band].rx.rx_cal_params.lna_switch_thr_low;
437 l1_config.std.lna_switch_thr_high_band1 = rf_band[tm_band].rx.rx_cal_params.lna_switch_thr_high;
438 }
439 else if (tm_band == 1)
440 {
441 l1_config.std.g_magic_band2 = rf_band[tm_band].rx.rx_cal_params.g_magic;
442 l1_config.std.lna_att_band2 = rf_band[tm_band].rx.rx_cal_params.lna_att;
443 l1_config.std.lna_switch_thr_low_band2 = rf_band[tm_band].rx.rx_cal_params.lna_switch_thr_low;
444 l1_config.std.lna_switch_thr_high_band2 = rf_band[tm_band].rx.rx_cal_params.lna_switch_thr_high;
445 }
446 else
447 {
448 tm_return->status = E_INVAL;
449 break;
450 }
451
452 tm_return->status = E_OK;
453 break;
454 }
455 case TX_CAL_EXTREME:
456 case RX_CAL_LEVEL:
457 {
458 tm_return->status = E_NOSUBSYS;
459 break;
460 }
461 #if L1_GPRS
462 case RLC_TX_BUFFER_CS1:
463 case RLC_TX_BUFFER_CS2:
464 case RLC_TX_BUFFER_CS3:
465 case RLC_TX_BUFFER_CS4:
466 {
467 UWORD8 i, buffer_size;
468
469 tm_return->index = index; // store index before it gets modified
470 tm_return->size = 0;
471
472 buffer_size = size/2 + size%2; // bytes will be concatenated into UWORD16
473
474 if (buffer_size > 27) //max. number of data bytes
475 {
476 tm_return->status = E_BADSIZE;
477 break;
478 }
479
480 // make sure that last byte is zero in case of odd number of bytes
481 table[size] = 0;
482
483 // init the whole buffer before downloading new data
484 for (i=0; i<27; i++)
485 l1_config.tmode.tx_params.rlc_buffer[i] = 0;
486
487 for (i=0; i<buffer_size; i++)
488 {
489 l1_config.tmode.tx_params.rlc_buffer[i] = (table[2*i+1] << 8) | table[2*i];
490 }
491 l1_config.tmode.tx_params.rlc_buffer_size = buffer_size;
492
493 tm_return->status = E_OK;
494 break;
495 }
496 #endif
497 case TX_DATA_BUFFER:
498 {
499 UWORD8 i;
500
501 tm_return->index = index; // store index before it gets modified
502 tm_return->size = 0;
503
504 if (size != 32) // 16 UWORD16 (containing 10 data bits each)
505 {
506 tm_return->status = E_BADSIZE;
507 break;
508 }
509
510 memcpy(&TM_ul_data, table, size);
511
512 for (i=0; i<16; i++)
513 {
514 TM_ul_data[i] = TM_ul_data[i] << 6;
515 }
516
517 tm_return->status = E_OK;
518 break;
519 }
520 default:
521 {
522 tm_return->status = E_BADINDEX;
523 break;
524 }
525 } // end switch
526 }
527
528 void Cust_tm_rf_table_read(T_TM_RETURN *tm_return, WORD8 index)
529 {
530 switch (index)
531 {
532 case RX_AGC_TABLE:
533 {
534 tm_return->size = sizeof(AGC_TABLE);
535 memcpy(tm_return->result, &AGC_TABLE[0], tm_return->size);
536 break;
537 }
538 case AFC_PARAMS:
539 {
540 #if (VCXO_ALGO == 1)
541 tm_return->size = 24; // 4 UWORD32's + 4 WORD16
542 #else
543 tm_return->size = 16; // 4 UWORD32's
544 #endif
545 memcpy(tm_return->result, &rf.afc.psi_sta_inv, tm_return->size);
546 break;
547 }
548 case RX_AGC_GLOBAL_PARAMS:
549 {
550 tm_return->size = 8; // 4 UWORD16's
551 memcpy(tm_return->result, &rf.rx.agc.low_agc_noise_thr, tm_return->size);
552
553 break;
554 }
555 case RX_IL_2_AGC_MAX:
556 {
557 tm_return->size = sizeof(rf.rx.agc.il2agc_max);
558 memcpy(tm_return->result, &rf.rx.agc.il2agc_max[0], tm_return->size);
559 break;
560 }
561 case RX_IL_2_AGC_PWR:
562 {
563 tm_return->size = sizeof(rf.rx.agc.il2agc_pwr);
564 memcpy(tm_return->result, &rf.rx.agc.il2agc_pwr[0], tm_return->size);
565 break;
566 }
567 case RX_IL_2_AGC_AV:
568 {
569 tm_return->size = sizeof(rf.rx.agc.il2agc_av);
570 memcpy(tm_return->result, &rf.rx.agc.il2agc_av[0], tm_return->size);
571 break;
572 }
573 case TX_LEVELS:
574 {
575 tm_return->size = sizeof(rf_band[tm_band].tx.levels);
576 memcpy(tm_return->result, &rf_band[tm_band].tx.levels[0], tm_return->size);
577 break;
578 }
579 case TX_CAL_CHAN: // generic for all bands
580 {
581 tm_return->size = sizeof(rf_band[tm_band].tx.chan_cal_table);
582 memcpy(tm_return->result, &rf_band[tm_band].tx.chan_cal_table[0][0], tm_return->size);
583 break;
584 }
585 case TX_CAL_TEMP: // generic for all bands
586 {
587 tm_return->size = sizeof(rf_band[tm_band].tx.temp);
588 memcpy(tm_return->result, &rf_band[tm_band].tx.temp[0], tm_return->size);
589 break;
590 }
591 case RX_CAL_CHAN: // generic for all bands
592 {
593 tm_return->size = sizeof(rf_band[tm_band].rx.agc_bands);
594 memcpy(tm_return->result, &rf_band[tm_band].rx.agc_bands[0], tm_return->size);
595 break;
596 }
597 case RX_CAL_TEMP: // generic for all bands
598 {
599 tm_return->size = sizeof(rf_band[tm_band].rx.temp);
600 memcpy(tm_return->result, &rf_band[tm_band].rx.temp[0], tm_return->size);
601 break;
602 }
603 case RX_AGC_PARAMS:
604 {
605 // WARNING: sizeof(rf.rx.rx_cal_params[band]) returns 12 because of alignment
606 tm_return->size = 10; // five UWORD16's
607 memcpy(tm_return->result, &rf_band[tm_band].rx.rx_cal_params, tm_return->size);
608 break;
609 }
610 case TX_CAL_EXTREME:
611 case RX_CAL_LEVEL:
612 {
613 tm_return->size = 0;
614 tm_return->status = E_NOSUBSYS;
615 return;
616 }
617
618 #if L1_GPRS
619 case RLC_TX_BUFFER_CS1:
620 case RLC_TX_BUFFER_CS2:
621 case RLC_TX_BUFFER_CS3:
622 case RLC_TX_BUFFER_CS4:
623 {
624 tm_return->size = l1_config.tmode.tx_params.rlc_buffer_size * 2; // UWORD16's
625 memcpy(tm_return->result, &l1_config.tmode.tx_params.rlc_buffer[0], tm_return->size);
626 break;
627 }
628 #endif
629
630 case TX_DATA_BUFFER:
631 {
632 UWORD8 i;
633 for (i=0; i<16; i++)
634 {
635 tm_return->result[2*i]=(TM_ul_data[i] >> 6) & 0x00FF;
636 tm_return->result[2*i+1]=(TM_ul_data[i] >> 14) & 0x0003;
637 }
638
639 tm_return->size = 32; //16*UWORD16
640 break;
641 }
642
643 #if (RF==35)
644 case RX_PLL_TUNING_TABLE:
645 {
646 tm_return->size = sizeof(pll_tuning); //6*UWORD16
647 memcpy(tm_return->result, &pll_tuning, tm_return->size);
648 pll_tuning.enable = 0;
649 break;
650 }
651 #endif
652
653 default:
654 {
655 tm_return->size = 0;
656 tm_return->status = E_BADINDEX;
657 return;
658 }
659 } // end switch
660
661 tm_return->index = index;
662 tm_return->status = E_OK;
663 }
664
665 void Cust_tm_rx_param_write(T_TM_RETURN *tm_return, WORD16 index, UWORD16 value)
666 {
667 switch (index)
668 {
669 case RX_FRONT_DELAY:
670 {
671 //delay for dual band not implemented yet
672 rf.tx.prg_tx = value;
673 l1_config.params.prg_tx_gsm = rf.tx.prg_tx;
674 l1_config.params.prg_tx_dcs = rf.tx.prg_tx;
675
676 tm_return->status = E_OK;
677 break;
678 }
679 default:
680 {
681 tm_return->status = E_BADINDEX;
682 break;
683 }
684 } // end switch
685 }
686
687 void Cust_tm_rx_param_read(T_TM_RETURN *tm_return, WORD16 index)
688 {
689 volatile UWORD16 value;
690
691 switch (index)
692 {
693 case RX_FRONT_DELAY:
694 {
695 value = rf.tx.prg_tx;
696 break;
697 }
698 default:
699 {
700 tm_return->status = E_BADINDEX;
701 tm_return->size = 0;
702 return;
703 }
704 } // end switch
705
706 memcpy(tm_return->result, (UWORD8 *)&value, 2);
707 tm_return->size = 2;
708 tm_return->status = E_OK;
709 }
710
711 void Cust_tm_tx_param_write(T_TM_RETURN *tm_return, WORD16 index, UWORD16 value, UWORD8 band)
712 {
713 switch (index)
714 {
715 case TX_APC_DAC:
716 {
717 // generic for all bands
718 rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].apc = value;
719
720 tm_return->status = E_OK;
721 break;
722 }
723 case TX_RAMP_TEMPLATE:
724 {
725 if (value >= sizeof(rf_band[tm_band].tx.ramp_tables)/sizeof(rf_band[tm_band].tx.ramp_tables[0])) // [0..15]
726 {
727 tm_return->status = E_INVAL;
728 break;
729 }
730
731 // generic for all bands
732 rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].ramp_index = value;
733
734 tm_return->status = E_OK;
735 l1_config.tmode.rf_params.reload_ramps_flag = 1;
736 break;
737 }
738 case TX_CHAN_CAL_TABLE:
739 {
740 if (value >= sizeof(rf_band[tm_band].tx.chan_cal_table)/sizeof(rf_band[tm_band].tx.chan_cal_table[0]))
741 {
742 tm_return->status = E_INVAL;
743 break;
744 }
745
746 // generic for all bands
747 rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].chan_cal_index = value;
748
749 tm_return->status = E_OK;
750
751 break;
752 }
753 case TX_BURST_TYPE:
754 {
755 if (value > 1) // [0..1]
756 {
757 tm_return->status = E_INVAL;
758 break;
759 }
760 l1_config.tmode.tx_params.burst_type = value;
761 tm_return->status = E_OK;
762 break;
763 }
764 case TX_BURST_DATA:
765 {
766 // range is [0..10], currently we support [0..13] at the moment
767 if (value > 13)
768 {
769 tm_return->status = E_INVAL;
770 break;
771 }
772 l1_config.tmode.tx_params.burst_data = value;
773 tm_return->status = E_OK;
774 break;
775 }
776 case TX_TRAINING_SEQ:
777 {
778 if (value > 7) // [0..7]
779 {
780 tm_return->status = E_INVAL;
781 break;
782 }
783 l1_config.tmode.tx_params.tsc = value;
784 tm_return->status = E_OK;
785 break;
786 }
787 default:
788 {
789 tm_return->status = E_BADINDEX;
790 break;
791 }
792 } // end switch
793 }
794
795 void Cust_tm_tx_param_read(T_TM_RETURN *tm_return, WORD16 index, UWORD8 band)
796 {
797 volatile UWORD16 value;
798
799 switch (index)
800 {
801 case TX_PWR_LEVEL:
802 {
803 value = l1_config.tmode.tx_params.txpwr;
804 break;
805 }
806 case TX_APC_DAC:
807 {
808 value = rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].apc;
809 break;
810 }
811 case TX_RAMP_TEMPLATE:
812 {
813 value = rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].ramp_index;
814 break;
815 }
816 case TX_CHAN_CAL_TABLE:
817 {
818 value = rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].chan_cal_index;
819 break;
820 }
821 case TX_BURST_TYPE:
822 {
823 value = l1_config.tmode.tx_params.burst_type;
824 break;
825 }
826 case TX_BURST_DATA:
827 {
828 value = l1_config.tmode.tx_params.burst_data;
829 break;
830 }
831 case TX_TIMING_ADVANCE:
832 {
833 value = l1_config.tmode.tx_params.timing_advance;
834 break;
835 }
836 case TX_TRAINING_SEQ:
837 {
838 value = l1_config.tmode.tx_params.tsc;
839 break;
840 }
841 case TX_PWR_SKIP:
842 {
843 value = l1_config.tmode.tx_params.txpwr_skip;
844 break;
845 }
846 #if L1_GPRS
847 case TX_GPRS_POWER0:
848 case TX_GPRS_POWER1:
849 case TX_GPRS_POWER2:
850 case TX_GPRS_POWER3:
851 case TX_GPRS_POWER4:
852 case TX_GPRS_POWER5:
853 case TX_GPRS_POWER6:
854 case TX_GPRS_POWER7:
855 {
856 value = l1_config.tmode.tx_params.txpwr_gprs[index - TX_GPRS_POWER0];
857 break;
858 }
859 case TX_GPRS_SLOTS:
860 {
861 value = l1_config.tmode.tx_params.timeslot_alloc;
862 break;
863 }
864 case TX_GPRS_CODING:
865 {
866 value = l1_config.tmode.tx_params.coding_scheme;
867 break;
868 }
869 #endif
870 default:
871 {
872 tm_return->status = E_BADINDEX;
873 tm_return->size = 0;
874 return;
875 }
876 } // end switch
877
878 memcpy(tm_return->result, (UWORD8 *)&value, 2);
879 tm_return->size = 2;
880 tm_return->status = E_OK;
881 }
882
883 void Cust_tm_tx_template_write(T_TM_RETURN *tm_return, WORD8 index, UWORD8 size, UWORD8 table[])
884 {
885 if (index >= sizeof(rf_band[tm_band].tx.ramp_tables)/sizeof(T_TX_RAMP))
886 {
887 tm_return->status = E_BADINDEX;
888 }
889 else if (size != sizeof(T_TX_RAMP))
890 {
891 // We are writing both the up and down ramps; size must be exact.
892 tm_return->status = E_BADSIZE;
893 }
894 else
895 {
896 memcpy(rf_band[tm_band].tx.ramp_tables[index].ramp_up, &table[0], size/2);
897 memcpy(rf_band[tm_band].tx.ramp_tables[index].ramp_down, &table[size/2], size/2);
898 tm_return->status = E_OK;
899 l1_config.tmode.rf_params.reload_ramps_flag = 1;
900 }
901
902 tm_return->index = index;
903 tm_return->size = 0;
904 }
905
906 void Cust_tm_tx_template_read(T_TM_RETURN *tm_return, WORD8 index)
907 {
908 tm_return->index = index;
909
910 if (index >= sizeof(rf_band[tm_band].tx.ramp_tables)/sizeof(T_TX_RAMP))
911 {
912 tm_return->status = E_BADINDEX;
913 tm_return->size = 0;
914 return;
915 }
916
917 memcpy(&tm_return->result[0], rf_band[tm_band].tx.ramp_tables[index].ramp_up, sizeof(rf_band[tm_band].tx.ramp_tables[index].ramp_up));
918 memcpy(&tm_return->result[sizeof(rf_band[tm_band].tx.ramp_tables[index].ramp_up)], rf_band[tm_band].tx.ramp_tables[index].ramp_down, sizeof(rf_band[tm_band].tx.ramp_tables[index].ramp_down));
919 tm_return->size = sizeof(rf_band[tm_band].tx.ramp_tables[index]);
920 tm_return->status = E_OK;
921 }
922
923 void Cust_tm_misc_param_write(T_TM_RETURN *tm_return, WORD16 index, UWORD16 value)
924 {
925 switch (index)
926 {
927 case GPIOSTATE0:
928 case GPIODIR0:
929 case GPIOSTATE1:
930 case GPIODIR1:
931 case GPIOSTATE0P:
932 case GPIODIR0P:
933 case GPIOSTATE1P:
934 case GPIODIR1P:
935 {
936 tm_return->status = E_NOSUBSYS;
937 break;
938 }
939 case CONVERTED_ADC0:
940 case CONVERTED_ADC1:
941 case CONVERTED_ADC2:
942 case CONVERTED_ADC3:
943 case CONVERTED_ADC4:
944 case CONVERTED_ADC5:
945 case CONVERTED_ADC6:
946 case CONVERTED_ADC7:
947 case CONVERTED_ADC8:
948 {
949 adc.converted[index - CONVERTED_ADC0] = value;
950 tm_return->status = E_OK;
951 break;
952 }
953
954 case RAW_ADC0:
955 case RAW_ADC1:
956 case RAW_ADC2:
957 case RAW_ADC3:
958 case RAW_ADC4:
959 case RAW_ADC5:
960 case RAW_ADC6:
961 case RAW_ADC7:
962 case RAW_ADC8:
963 {
964 adc.raw[index - RAW_ADC0] = value;
965 tm_return->status = E_OK;
966 break;
967 }
968
969 case ADC0_COEFF_A:
970 case ADC1_COEFF_A:
971 case ADC2_COEFF_A:
972 case ADC3_COEFF_A:
973 case ADC4_COEFF_A:
974 case ADC5_COEFF_A:
975 case ADC6_COEFF_A:
976 case ADC7_COEFF_A:
977 case ADC8_COEFF_A:
978 {
979 adc_cal.a[index - ADC0_COEFF_A] = value;
980 tm_return->status = E_OK;
981 break;
982 }
983
984 case ADC0_COEFF_B:
985 case ADC1_COEFF_B:
986 case ADC2_COEFF_B:
987 case ADC3_COEFF_B:
988 case ADC4_COEFF_B:
989 case ADC5_COEFF_B:
990 case ADC6_COEFF_B:
991 case ADC7_COEFF_B:
992 case ADC8_COEFF_B:
993 {
994 adc_cal.b[index - ADC0_COEFF_B] = value;
995 tm_return->status = E_OK;
996 break;
997 }
998 case SLEEP_MODE:
999 {
1000 tm_return->status = E_NOSUBSYS;
1001 break;
1002 }
1003 default:
1004 {
1005 tm_return->status = E_BADINDEX;
1006 break;
1007 }
1008 } // end switch
1009 }
1010
1011 void Cust_tm_misc_param_read(T_TM_RETURN *tm_return, WORD16 index)
1012 {
1013 volatile UWORD16 value;
1014
1015 switch (index)
1016 {
1017 case GPIOSTATE0:
1018 case GPIODIR0:
1019 case GPIOSTATE1:
1020 case GPIODIR1:
1021 case GPIOSTATE0P:
1022 case GPIODIR0P:
1023 case GPIOSTATE1P:
1024 case GPIODIR1P:
1025 {
1026 tm_return->status = E_NOSUBSYS;
1027 tm_return->size = 0;
1028 return;
1029 }
1030 case CONVERTED_ADC0:
1031 case CONVERTED_ADC1:
1032 case CONVERTED_ADC2:
1033 case CONVERTED_ADC3:
1034 case CONVERTED_ADC4:
1035 case CONVERTED_ADC5:
1036 case CONVERTED_ADC6:
1037 case CONVERTED_ADC7:
1038 case CONVERTED_ADC8:
1039 {
1040 value = adc.converted[index - CONVERTED_ADC0];
1041 break;
1042 }
1043 case RAW_ADC0:
1044 case RAW_ADC1:
1045 case RAW_ADC2:
1046 case RAW_ADC3:
1047 case RAW_ADC4:
1048 case RAW_ADC5:
1049 case RAW_ADC6:
1050 case RAW_ADC7:
1051 case RAW_ADC8:
1052 {
1053 value = adc.raw[index - RAW_ADC0];
1054 break;
1055 }
1056 case ADC0_COEFF_A:
1057 case ADC1_COEFF_A:
1058 case ADC2_COEFF_A:
1059 case ADC3_COEFF_A:
1060 case ADC4_COEFF_A:
1061 case ADC5_COEFF_A:
1062 case ADC6_COEFF_A:
1063 case ADC7_COEFF_A:
1064 case ADC8_COEFF_A:
1065 {
1066 value = adc_cal.a[index - ADC0_COEFF_A];
1067 break;
1068 }
1069 case ADC0_COEFF_B:
1070 case ADC1_COEFF_B:
1071 case ADC2_COEFF_B:
1072 case ADC3_COEFF_B:
1073 case ADC4_COEFF_B:
1074 case ADC5_COEFF_B:
1075 case ADC6_COEFF_B:
1076 case ADC7_COEFF_B:
1077 case ADC8_COEFF_B:
1078 {
1079 value = adc_cal.b[index - ADC0_COEFF_B];
1080 break;
1081 }
1082 case SLEEP_MODE:
1083 {
1084 tm_return->status = E_NOSUBSYS;
1085 tm_return->size = 0;
1086 return;
1087 }
1088 default:
1089 {
1090 tm_return->status = E_BADINDEX;
1091 tm_return->size = 0;
1092 return;
1093 }
1094 } // end switch
1095
1096 memcpy(tm_return->result, (UWORD8 *)&value, 2);
1097 tm_return->size = 2;
1098 tm_return->status = E_OK;
1099 }
1100
1101 void Cust_tm_misc_enable(T_TM_RETURN *tm_return, WORD16 action)
1102 {
1103 UWORD8 status;
1104
1105 // FIXME: This enum really should go into testmode header file.
1106 enum ME_CFG_WRITE_E {
1107 CFG_WRITE_MKDIRS = 100,
1108 CFG_WRITE_RF_CAL = 102,
1109 CFG_WRITE_RF_CFG = 103,
1110 CFG_WRITE_TX_CAL = 104,
1111 CFG_WRITE_TX_CFG = 105,
1112 CFG_WRITE_RX_CAL = 106,
1113 CFG_WRITE_RX_CFG = 107,
1114 CFG_WRITE_SYS_CAL = 108,
1115 CFG_WRITE_SYS_CFG = 109
1116 };
1117
1118 tm_return->size = 0;
1119 tm_return->index = action;
1120 tm_return->status = E_OK;
1121
1122 // FIXME: This code should actually be in misc_enable()
1123 switch(action)
1124 {
1125 case CFG_WRITE_MKDIRS:
1126 ffs_mkdir("/gsm");
1127 ffs_mkdir("/pcm");
1128 ffs_mkdir("/sys");
1129 ffs_mkdir("/mmi");
1130 ffs_mkdir("/vos");
1131 ffs_mkdir("/var");
1132 ffs_mkdir("/gsm/rf");
1133 ffs_mkdir("/gsm/com");
1134 ffs_mkdir("/vos/vm");
1135 ffs_mkdir("/vos/vrm");
1136 ffs_mkdir("/vos/vrp");
1137 ffs_mkdir("/var/log");
1138 ffs_mkdir("/var/tst");
1139 ffs_mkdir("/gsm/rf/tx");
1140 ffs_mkdir("/gsm/rf/rx");
1141 break;
1142 case CFG_WRITE_RF_CAL: config_ffs_write('f'); break;
1143 case CFG_WRITE_RF_CFG: config_ffs_write('F'); break;
1144 case CFG_WRITE_TX_CAL: config_ffs_write('t'); break;
1145 case CFG_WRITE_TX_CFG: config_ffs_write('T'); break;
1146 case CFG_WRITE_RX_CAL: config_ffs_write('r'); break;
1147 case CFG_WRITE_RX_CFG: config_ffs_write('R'); break;
1148 case CFG_WRITE_SYS_CAL: config_ffs_write('s'); break;
1149 case CFG_WRITE_SYS_CFG: config_ffs_write('S'); break;
1150 default:
1151 tm_return->status = E_BADINDEX;
1152 }
1153 }
1154
1155 void Cust_tm_special_param_write(T_TM_RETURN *tm_return, WORD16 index, UWORD16 value)
1156 {
1157 tm_return->size = 0;
1158 tm_return->index = index;
1159 tm_return->status = E_NOSYS;
1160 }
1161
1162 void Cust_tm_special_param_read(T_TM_RETURN *tm_return, WORD16 index)
1163 {
1164 tm_return->size = 0;
1165 tm_return->index = index;
1166 tm_return->status = E_NOSYS;
1167 }
1168
1169 void Cust_tm_special_table_write(T_TM_RETURN *tm_return, WORD8 index, UWORD8 size, UWORD8 table[])
1170 {
1171 tm_return->size = 0;
1172 tm_return->index = index;
1173 tm_return->status = E_NOSYS;
1174 }
1175
1176 void Cust_tm_special_table_read(T_TM_RETURN *tm_return, WORD8 index)
1177 {
1178 tm_return->size = 0;
1179 tm_return->index = index;
1180 tm_return->status = E_NOSYS;
1181 }
1182
1183 void Cust_tm_special_enable(T_TM_RETURN *tm_return, WORD16 action)
1184 {
1185 tm_return->size = 0;
1186 tm_return->index = action;
1187 tm_return->status = E_NOSYS;
1188 }
1189
1190 #endif // TESTMODE