FreeCalypso > hg > fc-tourmaline
comparison src/cs/layer1/tm_cfile/l1tm_stats.c @ 0:4e78acac3d88
src/{condat,cs,gpf,nucleus}: import from Selenite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 16 Oct 2020 06:23:26 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4e78acac3d88 |
---|---|
1 /************* Revision Controle System Header ************* | |
2 * GSM Layer 1 software | |
3 * L1TM_STAT.C | |
4 * | |
5 * Filename l1tm_stats.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 | |
15 #include <string.h> | |
16 #include "l1_types.h" | |
17 #include "sys_types.h" | |
18 #include "l1_const.h" | |
19 #include "l1_time.h" | |
20 #include "l1_signa.h" | |
21 | |
22 #include "l1tm_defty.h" | |
23 | |
24 #if (AUDIO_TASK == 1) | |
25 #include "l1audio_const.h" | |
26 #include "l1audio_cust.h" | |
27 #include "l1audio_defty.h" | |
28 #endif | |
29 | |
30 #if (L1_GTT == 1) | |
31 #include "l1gtt_const.h" | |
32 #include "l1gtt_defty.h" | |
33 #endif | |
34 | |
35 #if (L1_MP3 == 1) | |
36 #include "l1mp3_defty.h" | |
37 #endif | |
38 | |
39 #if (L1_MIDI == 1) | |
40 #include "l1midi_defty.h" | |
41 #endif | |
42 | |
43 #include "l1_defty.h" | |
44 #include "cust_os.h" | |
45 #include "l1_msgty.h" | |
46 #include "l1_varex.h" | |
47 #include "l1_proto.h" | |
48 | |
49 #include "l1tm_msgty.h" | |
50 #include "l1tm_varex.h" | |
51 | |
52 /***********************************************************************/ | |
53 /* TESTMODE 3.X */ | |
54 /***********************************************************************/ | |
55 | |
56 /* External function prototypes */ | |
57 /*------------------------------*/ | |
58 void l1tm_stats_read(T_TM_RETURN *tm_return, WORD16 type, UWORD16 bitmask); | |
59 void l1a_tmode_send_ul_msg(T_TM_RETURN *tm_ret); | |
60 | |
61 /* Internal function prototypes */ | |
62 /*------------------------------*/ | |
63 void l1tm_stats_compute(UWORD32 pm, UWORD32 toa, UWORD32 snr, WORD16 angle); | |
64 void l1tm_stats_auto_result_reset_loops(void); | |
65 void l1tm_reset_rx_stats(void); | |
66 | |
67 | |
68 void l1tm_stats_fb_confirm (T_TMODE_FB_CON *prim, WORD32 test) | |
69 // loop management done in L1A state machine | |
70 { | |
71 | |
72 l1tm.tmode_stats.loop_count++; | |
73 l1tm.tmode_stats.flag_recent = prim->fb_flag; | |
74 | |
75 if (prim->fb_flag) | |
76 { | |
77 l1tm.tmode_stats.flag_count++; | |
78 } | |
79 | |
80 if (prim->fb_flag) | |
81 // We only save stats from a SUCCESS (including PM) | |
82 { | |
83 #if (TOA_ALGO == 2) | |
84 l1tm_stats_compute(prim->pm_fullres, ((prim->toa)<<2), prim->snr, prim->angle); | |
85 #else | |
86 l1tm_stats_compute(prim->pm_fullres, prim->toa, prim->snr, prim->angle); | |
87 #endif | |
88 } | |
89 | |
90 l1tm_stats_auto_result_reset_loops(); | |
91 } | |
92 | |
93 void l1tm_stats_sb_confirm (T_TMODE_NCELL_SYNC_IND *prim, WORD32 test) | |
94 // loop management done in L1A state machine | |
95 { | |
96 | |
97 l1tm.tmode_stats.loop_count++; | |
98 l1tm.tmode_stats.flag_recent = prim->sb_flag; | |
99 | |
100 if (prim->sb_flag) | |
101 { | |
102 l1tm.tmode_stats.flag_count++; | |
103 l1tm.tmode_stats.bsic = prim->bsic; | |
104 } | |
105 | |
106 if (prim->sb_flag) | |
107 // we only save stats from a SUCCESS (including PM) | |
108 { | |
109 #if (TOA_ALGO == 2) | |
110 l1tm_stats_compute(prim->pm_fullres, ((prim->toa)<<2), prim->snr, prim->angle); | |
111 #else | |
112 l1tm_stats_compute(prim->pm_fullres, prim->toa, prim->snr, prim->angle); | |
113 #endif | |
114 } | |
115 | |
116 l1tm_stats_auto_result_reset_loops(); | |
117 } | |
118 | |
119 void l1tm_stats_bcch_confirm (T_TMODE_BCCHS_CON *prim) | |
120 // loop management done here after stats management | |
121 // (the only stat is pass/fail) | |
122 { | |
123 | |
124 l1tm.tmode_stats.loop_count++; | |
125 | |
126 if (prim->error_flag == FALSE) | |
127 { | |
128 l1tm.tmode_stats.flag_count++; | |
129 l1tm.tmode_stats.flag_recent = 1; | |
130 l1tm.tmode_stats.bsic = l1a_l1s_com.Scell_info.bsic; | |
131 } | |
132 else | |
133 { | |
134 l1tm.tmode_stats.flag_recent = 0; | |
135 } | |
136 | |
137 l1tm_stats_auto_result_reset_loops(); | |
138 } | |
139 | |
140 void l1tm_stats_tch_confirm (T_TMODE_TCH_INFO *prim) | |
141 // loop management and stats management done here | |
142 { | |
143 | |
144 // Update statistics only if downlink task enabled: DL-only or DL+UL | |
145 if((l1_config.tmode.rf_params.down_up & TMODE_DOWNLINK) && | |
146 l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS) | |
147 { | |
148 l1tm.tmode_stats.loop_count++; | |
149 | |
150 // TCH statistics are based on (accumulated) bit errors | |
151 // Stats are computed independently from the RXQUAL | |
152 // Discard first 2 blocks of TCH => always wrong if start not on block boundary | |
153 if (l1tm.tmode_stats.loop_count > 2) | |
154 { | |
155 l1tm.tmode_stats.qual_acc_full += prim->qual_full; | |
156 l1tm.tmode_stats.qual_nbr_meas_full += prim->qual_nbr_meas_full; | |
157 // fixed point unsigned F9.7 format | |
158 l1tm.tmode_stats.flag_count = (WORD32)(((l1tm.tmode_stats.qual_acc_full * 100)<<8)/(l1tm.tmode_stats.qual_nbr_meas_full)); | |
159 } | |
160 | |
161 l1tm.tmode_stats.flag_recent = 1; | |
162 l1tm.tmode_stats.bsic = l1a_l1s_com.Scell_info.bsic; | |
163 | |
164 l1tm_stats_compute(prim->pm_fullres, prim->toa, prim->snr, prim->angle); | |
165 | |
166 l1tm_stats_auto_result_reset_loops(); | |
167 | |
168 } // end if DL-only or DL+UL | |
169 } | |
170 | |
171 void l1tm_stats_mon_confirm (T_TMODE_FB_CON *prim) | |
172 // loop management done in L1A state machine | |
173 { | |
174 | |
175 l1tm.tmode_stats.loop_count++; | |
176 l1tm.tmode_stats.flag_recent = prim->fb_flag; | |
177 | |
178 if (prim->fb_flag) | |
179 { | |
180 l1tm.tmode_stats.flag_count++; | |
181 } | |
182 | |
183 if (prim->fb_flag) | |
184 // we only save stats from a SUCCESS (including PM) | |
185 { | |
186 l1tm_stats_compute(prim->pm_fullres, prim->toa, prim->snr, prim->angle); | |
187 } | |
188 | |
189 l1tm_stats_auto_result_reset_loops(); | |
190 } | |
191 | |
192 /*void l1tm_stats_ra_confirm (T_TMODE_RA_DONE *prim) | |
193 // this function is only called when the RACH test is done | |
194 { | |
195 //l1tm.tmode_stats.fn = prim->fn; | |
196 | |
197 l1tm.tmode_state.dedicated_active = 0; | |
198 }*/ | |
199 | |
200 void l1tm_stats_full_list_meas_confirm(T_TMODE_RXLEV_REQ *prim) | |
201 { | |
202 T_TM_RETURN tm_ret; | |
203 WORD16 stats_type = 2; // recent stats | |
204 UWORD16 stats_bitmask = 0x0003; // for power measurement force rxlev and pm | |
205 | |
206 | |
207 l1tm.tmode_stats.rssi_recent = prim->power_array->accum_power_result; | |
208 l1tm_stats_read(&tm_ret, stats_type, stats_bitmask); | |
209 // above function sets tm_ret.status, tm_ret.result[], tm_ret.index, tm_ret.size | |
210 | |
211 #if (ETM_PROTOCOL == 1) | |
212 tm_ret.mid = ETM_RF; | |
213 #endif | |
214 | |
215 tm_ret.cid = STATS_READ; | |
216 l1a_tmode_send_ul_msg(&tm_ret); | |
217 } | |
218 | |
219 #if L1_GPRS | |
220 void l1tm_stats_pdtch_confirm (T_TMODE_PDTCH_INFO *prim) | |
221 // loop management and stats management done here | |
222 { | |
223 UWORD8 ts; | |
224 UWORD8 bit_map = 0x80; | |
225 | |
226 l1tm.tmode_stats.loop_count++; | |
227 l1tm.tmode_stats.bsic = l1a_l1s_com.Scell_info.bsic; | |
228 | |
229 // count the number of successes over all time slots allocated for stats within one block | |
230 for (ts=0;ts<8;ts++) | |
231 { | |
232 if (bit_map & l1_config.tmode.stats_config.stat_gprs_slots) | |
233 { | |
234 // if crc_error[ts]=FALSE the block is decoded successfully | |
235 if (!prim->crc_error_tbl[ts]) | |
236 l1tm.tmode_stats.flag_count ++; | |
237 } | |
238 bit_map>>=1; | |
239 } | |
240 | |
241 // TM stats are collected over one block (4 frames) | |
242 l1tm_stats_compute(prim->pm_fullres, prim->toa, prim->snr, prim->angle); | |
243 | |
244 l1tm_stats_auto_result_reset_loops(); | |
245 | |
246 } | |
247 #endif | |
248 | |
249 void l1tm_stats_compute(UWORD32 pm, UWORD32 toa, UWORD32 snr, WORD16 angle) | |
250 { | |
251 // PM STATS | |
252 l1tm.tmode_stats.pm_recent = pm; | |
253 l1tm.tmode_stats.pm_sum += pm; | |
254 l1tm.tmode_stats.pm_sq_sum += (pm*pm); | |
255 | |
256 // TOA STATS | |
257 l1tm.tmode_stats.toa_recent = toa; | |
258 l1tm.tmode_stats.toa_sum += toa; | |
259 l1tm.tmode_stats.toa_sq_sum += (toa*toa); | |
260 | |
261 // ANGLE STATS | |
262 l1tm.tmode_stats.angle_recent = angle; | |
263 l1tm.tmode_stats.angle_sum += angle; | |
264 l1tm.tmode_stats.angle_sq_sum += (angle*angle); | |
265 if (angle < l1tm.tmode_stats.angle_min ) | |
266 { | |
267 l1tm.tmode_stats.angle_min = angle; | |
268 } | |
269 if (angle > l1tm.tmode_stats.angle_max ) | |
270 { | |
271 l1tm.tmode_stats.angle_max = angle; | |
272 } | |
273 | |
274 // SNR STATS | |
275 l1tm.tmode_stats.snr_recent = snr; | |
276 l1tm.tmode_stats.snr_sum += snr; | |
277 l1tm.tmode_stats.snr_sq_sum += (snr*snr); | |
278 } | |
279 | |
280 void l1tm_stats_auto_result_reset_loops(void) | |
281 { | |
282 T_TM_RETURN tm_ret; | |
283 | |
284 if (l1_config.tmode.stats_config.auto_result_loops) | |
285 { | |
286 if ( (l1tm.tmode_stats.loop_count % l1_config.tmode.stats_config.auto_result_loops) == 0) | |
287 // time to report current stats. call l1tm_stats_read | |
288 { | |
289 l1tm_stats_read(&tm_ret, l1_config.tmode.stats_config.stat_type, l1_config.tmode.stats_config.stat_bitmask); | |
290 // above function sets tm_ret.status, tm_ret.result[], tm_ret.index, tm_ret.size | |
291 | |
292 #if (ETM_PROTOCOL == 1) | |
293 tm_ret.mid = ETM_RF; | |
294 #endif | |
295 | |
296 tm_ret.cid = STATS_READ; | |
297 l1a_tmode_send_ul_msg(&tm_ret); | |
298 } | |
299 } | |
300 | |
301 if (l1_config.tmode.stats_config.auto_reset_loops) | |
302 { | |
303 if ((l1tm.tmode_stats.loop_count % l1_config.tmode.stats_config.auto_reset_loops) == 0) | |
304 // time to reset stats. | |
305 { | |
306 l1tm_reset_rx_stats(); | |
307 // resets stats accumulators and success/runs counters but not master loop counter for task. | |
308 } | |
309 } | |
310 } | |
311 | |
312 /**************************************************************************** | |
313 Function: l1tm_is_rx_counter_done | |
314 Input: none | |
315 Output: 1 = done; | |
316 0 = not done. | |
317 | |
318 Checks to see if the RX loop should be stopped, and increments counter. | |
319 This counter is used in all RX functions. | |
320 *****************************************************************************/ | |
321 BOOL l1tm_is_rx_counter_done(void) | |
322 // another T_TM_RETURN allocated here for auto acknowledge of rf_enable operation. | |
323 // to help save stack we could pass in a pointer to the tm_return structure, | |
324 // then save the current values | |
325 { | |
326 T_TM_RETURN_ABBREV tm_ret; | |
327 | |
328 if (l1_config.tmode.stats_config.num_loops != 0) // 0 = infinite loop | |
329 { | |
330 l1tm.tmode_state.rx_counter++; | |
331 if (l1tm.tmode_state.rx_counter >= l1_config.tmode.stats_config.num_loops) | |
332 { | |
333 // acknowledge end of RF_ENABLE operation | |
334 | |
335 tm_ret.cid = RF_ENABLE; | |
336 tm_ret.index = 0; // No index value is sent | |
337 tm_ret.status = E_FINISHED; | |
338 | |
339 tm_ret.size = 1; | |
340 tm_ret.result[0] = 1; | |
341 l1a_tmode_send_ul_msg((T_TM_RETURN *) &tm_ret); | |
342 | |
343 return 1; | |
344 } | |
345 else | |
346 { | |
347 return 0; | |
348 } | |
349 } | |
350 else // infinite loop | |
351 { | |
352 return 0; | |
353 } | |
354 } | |
355 | |
356 void l1tm_reset_rx_state(void) | |
357 { | |
358 l1tm.tmode_state.rx_counter = 0; | |
359 l1tm.tmode_state.num_bcchs = 0; | |
360 } | |
361 | |
362 void l1tm_reset_rx_stats(void) | |
363 { | |
364 UWORD32 i; | |
365 | |
366 l1tm.tmode_stats.toa_sum = 0; | |
367 l1tm.tmode_stats.toa_sq_sum = 0; | |
368 l1tm.tmode_stats.toa_recent = 0; | |
369 l1tm.tmode_stats.rssi_recent = 0; | |
370 l1tm.tmode_stats.pm_sum = 0; | |
371 l1tm.tmode_stats.pm_sq_sum = 0; | |
372 l1tm.tmode_stats.pm_recent = 0; | |
373 l1tm.tmode_stats.angle_sum = 0; | |
374 l1tm.tmode_stats.angle_sq_sum = 0; | |
375 l1tm.tmode_stats.angle_min = +32767; | |
376 l1tm.tmode_stats.angle_max = -32768; | |
377 l1tm.tmode_stats.angle_recent = 0; | |
378 l1tm.tmode_stats.snr_sum = 0; | |
379 l1tm.tmode_stats.snr_sq_sum = 0; | |
380 l1tm.tmode_stats.snr_recent = 0; | |
381 l1tm.tmode_stats.loop_count = 0; | |
382 l1tm.tmode_stats.flag_count = 0; | |
383 l1tm.tmode_stats.fn = 0; | |
384 l1tm.tmode_stats.bsic = 0; | |
385 l1tm.tmode_stats.qual_acc_full = 0; | |
386 l1tm.tmode_stats.qual_nbr_meas_full = 0; | |
387 | |
388 for (i=0;i<4;i++) | |
389 l1tm.tmode_stats.rssi_fifo[i] = 0; | |
390 | |
391 #if L1_GPRS | |
392 l1tm.tmode_stats.nb_dl_pdtch_slots = 0; | |
393 #if 0 /* FreeCalypso TCS211 reconstruction: LoCosto-ism removed */ | |
394 // Stats Bler | |
395 l1tm.tmode_stats.bler_total_blocks = 0; | |
396 for (i=0;i<4;i++) | |
397 l1tm.tmode_stats.bler_crc[i] = 0; | |
398 #endif | |
399 #endif | |
400 } | |
401 | |
402 | |
403 #endif | |
404 |