FreeCalypso > hg > freecalypso-sw
comparison gsm-fw/ccd/freq_list_com.c @ 648:970d6199f2c5
gsm-fw/ccd/*.[ch]: initial import from the LoCosto source
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Thu, 04 Sep 2014 05:48:57 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
647:a60b375014e3 | 648:970d6199f2c5 |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : CCD | |
4 | Modul : freq_list_com.c | |
5 +----------------------------------------------------------------------------- | |
6 | Copyright 2004 Texas Instruments Deutschland GmbH | |
7 | All rights reserved. | |
8 | | |
9 | This file is confidential and a trade secret of Texas | |
10 | Instruments Deutschland GmbH | |
11 | The receipt of or possession of this file does not convey | |
12 | any rights to reproduce or disclose its contents or to | |
13 | manufacture, use, or sell anything it may describe, in | |
14 | whole, or in part, without the specific written consent of | |
15 | Texas Instruments Deutschland GmbH. | |
16 +----------------------------------------------------------------------------- | |
17 | Purpose : Definitions of common functions for decoding of types FDD_CI, | |
18 | TDD_CI and FREQ_LIST. | |
19 +----------------------------------------------------------------------------- | |
20 */ | |
21 | |
22 #define CDC_FREQ_LIST_COM_C | |
23 | |
24 /* | |
25 * standard definitions like GLOBAL, UCHAR, ERROR etc. | |
26 */ | |
27 #include "typedefs.h" | |
28 #include "header.h" | |
29 | |
30 /* | |
31 * Types and functions for bit access and manipulation | |
32 */ | |
33 #include "ccd_globs.h" | |
34 #include "bitfun.h" | |
35 | |
36 /* | |
37 * Error codes and prototypes of exported functions by CCD | |
38 */ | |
39 #include "ccdapi.h" | |
40 | |
41 /* | |
42 * Prototypes of ccd internal functions | |
43 */ | |
44 #include "ccd.h" | |
45 | |
46 #ifndef RUN_INT_RAM | |
47 U8 ByteBitMask[]= {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x1}; | |
48 #endif /* !RUN_INT_RAM */ | |
49 | |
50 #ifndef RUN_INT_RAM | |
51 /* | |
52 * The following table indicates the number of W-parameters and their | |
53 * length in bits. A length of zero indicates the end of the table. | |
54 * For frequency lists the W-parameter in the 1024 range starts from | |
55 * bit 6 of the information element. | |
56 */ | |
57 const T_W_PARAM param_1024[9] = | |
58 { | |
59 /* | |
60 * length count | |
61 */ | |
62 10, 1, | |
63 9, 2, | |
64 8, 4, | |
65 7, 8, | |
66 6, 16, | |
67 5, 32, | |
68 4, 64, | |
69 3, 128, | |
70 0, 0 | |
71 }; | |
72 #endif /* !RUN_INT_RAM */ | |
73 | |
74 #ifndef RUN_INT_RAM | |
75 /* | |
76 * The following table indicates the number of W-parameters and their | |
77 * length in bits. A length of zero indicates the end of the table. | |
78 * For frequency lists the W-parameter in the 512 range starts from | |
79 * bit 7 of the information element. | |
80 */ | |
81 const T_W_PARAM param_512[10] = | |
82 { | |
83 /* | |
84 * length count | |
85 */ | |
86 10, 1, | |
87 9, 1, | |
88 8, 2, | |
89 7, 4, | |
90 6, 8, | |
91 5, 16, | |
92 4, 32, | |
93 3, 64, | |
94 2, 128, | |
95 0, 0 | |
96 }; | |
97 #endif /* !RUN_INT_RAM */ | |
98 | |
99 #ifndef RUN_INT_RAM | |
100 /* Attention for RUN_...: static function */ | |
101 /* | |
102 +--------------------------------------------------------------------+ | |
103 | PROJECT : CCD FUNCTION : for_modulo | | |
104 +--------------------------------------------------------------------+ | |
105 | |
106 PURPOSE : A modulo calculation function. The standard C-Operator | |
107 fails for negative values! (e.g. -4 mod 6 is 2 and not 4). | |
108 | |
109 */ | |
110 | |
111 /* static */ long for_modulo (long a, long b) | |
112 { | |
113 long result; | |
114 | |
115 /* Use standard C-Operator for calculation. */ | |
116 result = a % b; | |
117 | |
118 /* Correct the result for negative values. */ | |
119 if (result < 0) | |
120 { | |
121 result += b; | |
122 } | |
123 | |
124 return result; | |
125 } | |
126 #endif /* !RUN_INT_RAM */ | |
127 | |
128 #ifndef RUN_INT_RAM | |
129 /* Attention for RUN_...: static function */ | |
130 /* | |
131 +--------------------------------------------------------------------+ | |
132 | PROJECT : CCD FUNCTION : for_smodulo | | |
133 +--------------------------------------------------------------------+ | |
134 | |
135 PURPOSE : Similar to the modulo operator, but 0 smod n is n and | |
136 not 0. Same problem for negative values with the standard | |
137 C-Operator. | |
138 | |
139 */ | |
140 static long for_smodulo (long a, long b) | |
141 { | |
142 long result; | |
143 | |
144 /* Use standard C-Operator for calculation. */ | |
145 result = a % b; | |
146 | |
147 /* Correct the result for negative values. */ | |
148 if (result < 0) | |
149 { | |
150 result += b; | |
151 } | |
152 | |
153 /* Special handling for result equal 0 */ | |
154 if (result EQ 0) | |
155 { | |
156 result = b; | |
157 } | |
158 | |
159 return result; | |
160 } | |
161 #endif /* !RUN_INT_RAM */ | |
162 | |
163 #ifndef RUN_INT_RAM | |
164 /* Attention for RUN_...: static function */ | |
165 /* | |
166 +--------------------------------------------------------------------+ | |
167 | PROJECT : CCD FUNCTION : for_get_generation | | |
168 +--------------------------------------------------------------------+ | |
169 | |
170 PURPOSE : The function calculates the greatest power of 2 of the given | |
171 value. The algorithm simply looks to the position of the | |
172 highest bit. | |
173 | |
174 */ | |
175 | |
176 static U16 for_get_generation (U16 value) | |
177 { | |
178 int result = 0; | |
179 int i; | |
180 | |
181 | |
182 /* Check all 16 bit positions. */ | |
183 for (i = 0; i < 16; i++) | |
184 { | |
185 /* If bit is set, store the position. */ | |
186 if (value & 1) | |
187 { | |
188 result = i + 1; | |
189 } | |
190 | |
191 /* Shift value to have the next bit for comparision. */ | |
192 value = value >> 1; | |
193 } | |
194 | |
195 /* Return the highest position. */ | |
196 return result; | |
197 } | |
198 #endif /* !RUN_INT_RAM */ | |
199 | |
200 #ifndef RUN_INT_RAM | |
201 /* | |
202 +--------------------------------------------------------------------+ | |
203 | PROJECT : CCD FUNCTION : cdc_decode_frequencies | | |
204 +--------------------------------------------------------------------+ | |
205 | |
206 PURPOSE : The algorithm is according GSM 4.08 Annex J. It calculates | |
207 a frequency hopping list from the W-parameter. | |
208 | |
209 */ | |
210 void cdc_decode_frequencies (short original_range, | |
211 short *w, | |
212 short offset, | |
213 U8 callerID, | |
214 T_CCD_Globs *globs) | |
215 { | |
216 short g; | |
217 short k; | |
218 short j; | |
219 short index; | |
220 short n; | |
221 short range; | |
222 U16 channel; | |
223 U16 bitposition; | |
224 U8 *BitmapInStruct = globs->pstruct + globs->pstructOffs; | |
225 U16 first = 0; | |
226 U16 last = BITOFFSET_LIST; | |
227 U16 num = 0; | |
228 BOOL ReadW = TRUE; | |
229 | |
230 #ifdef DEBUG_CCD | |
231 TRACE_CCD (globs, "cdc_decode_frequencies()"); | |
232 #endif | |
233 | |
234 if (callerID != TDD_CI_LIST && w[0] == 0) | |
235 ReadW = FALSE; | |
236 for (k = 1; ReadW; k++) | |
237 { | |
238 ReadW = (w[k-1] != 0) ? 1 : 0; | |
239 /* | |
240 * The next loop follows the tree from child to parent, | |
241 * from the node of index K to the root (index 1). For each iteration the | |
242 * node of index INDEX is tackled. The corresponding range is RANGE, and N | |
243 * is the value of the element in the range defined by the node. | |
244 * | |
245 * The data are set to their initial values | |
246 */ | |
247 index = k; | |
248 n = w[index-1]; | |
249 g = for_get_generation (index); | |
250 j = (1 << (g-1)); | |
251 range = original_range / j; | |
252 | |
253 while (index > 1) | |
254 { | |
255 /* | |
256 * Due to the assumption that the original range is a power of two minus one, | |
257 * the range for the parent node can be easily computed, and does not depend | |
258 * upon whether the current node is a left or right child | |
259 */ | |
260 g = for_get_generation (index); | |
261 j = (1 << (g-1)); | |
262 range = 2 * range + 1; | |
263 | |
264 /* | |
265 * Let us note J := 2 g-1 , g being the generation of node INDEX. We have J = | |
266 * GREATEST_POWER_OF_2_LESSER_OR_EQUAL_TO(INDEX). The numbering used in the tree | |
267 * is such that the nodes of index J to J + J/2 - 1 are left children, and the nodes | |
268 * of index J/2 to J+J-1 are right children. Hence an easy test to | |
269 * distinguish left and right children: | |
270 */ | |
271 if (2 * index < 3 * j) | |
272 { | |
273 /* | |
274 * The next computation gives the index of the parent node of the node of index | |
275 * INDEX, for a left child : | |
276 */ | |
277 index = index - j / 2; | |
278 | |
279 /* | |
280 * The next formula is the inverse of the renumbering appearing in the encoding | |
281 * for a left child. It gives the value of the parent node in the range defined | |
282 * by the grand-parent node: | |
283 */ | |
284 n = (short)for_smodulo (n + w[index-1] + (range-1) / 2, range); | |
285 } | |
286 else | |
287 { | |
288 /* | |
289 * The next computation gives the index of the parent node of the node of index | |
290 * INDEX, for a right child : | |
291 */ | |
292 index = index - j; | |
293 | |
294 /* | |
295 * The next formula is the inverse of the renumbering appearing in the encoding | |
296 * for a right child: | |
297 */ | |
298 n = (short)for_smodulo (n + w[index-1], range); | |
299 } | |
300 } | |
301 | |
302 /* | |
303 * Write the calculated number for non-frequency types. | |
304 * For TDD_CI and TDD_CI: offset = 0 and original_range = 1023. | |
305 */ | |
306 channel = (U16)for_modulo (n+offset, 1024); | |
307 if (callerID == FDD_CI_LIST || callerID == TDD_CI_LIST) | |
308 { | |
309 *(U16*)(globs->pstruct + globs->pstructOffs) = (U16)channel; | |
310 globs->pstructOffs += 2; | |
311 } | |
312 /* Set the calculated channel number for frequency channel list.*/ | |
313 else | |
314 { | |
315 if (channel == 0) | |
316 { | |
317 bitposition = 0; | |
318 } | |
319 else | |
320 { | |
321 bitposition = (U16)(BITOFFSET_LIST - channel); | |
322 } | |
323 if (first > bitposition) | |
324 first = bitposition; | |
325 if (last < bitposition) | |
326 last = bitposition; | |
327 num++; | |
328 BitmapInStruct[bitposition >> 3] |= ByteBitMask[bitposition & 7]; | |
329 } | |
330 } | |
331 | |
332 /* For the bitmap type print the helpful information into the structure. */ | |
333 if (callerID == FREQUENCY_LIST) | |
334 { | |
335 *(U16*) (BitmapInStruct - 6) = first; | |
336 *(U16*) (BitmapInStruct - 6) = last; | |
337 *(U16*) (BitmapInStruct - 2) = num; | |
338 } | |
339 } | |
340 #endif /* !RUN_INT_RAM */ | |
341 | |
342 #ifndef RUN_INT_RAM | |
343 /* | |
344 +--------------------------------------------------------------------+ | |
345 | PROJECT : CCD FUNCTION : cdc_decode_param | | |
346 +--------------------------------------------------------------------+ | |
347 | |
348 PURPOSE : The information element contains a list of W-parameter. | |
349 The table param indicates how many W-parameter from each | |
350 length shall be inside. The function converts the bitstream | |
351 of the W-parameter to an array of W-parameter 16 bit values. | |
352 | |
353 */ | |
354 | |
355 void cdc_decode_param (const T_W_PARAM *param, | |
356 short *w, | |
357 U16 ListLength, | |
358 T_CCD_Globs *globs) | |
359 { | |
360 U8 end_detected = FALSE; | |
361 U16 w_index = 0; | |
362 U16 length = ListLength; | |
363 U16 act_length = param->length; | |
364 U16 act_counter = param->count; | |
365 U32 lvalue; | |
366 | |
367 #ifdef DEBUG_CCD | |
368 TRACE_CCD (globs, "cdc_decode_param()"); | |
369 #endif | |
370 | |
371 /* | |
372 * Decode values in the list until the end of the IE is detected. | |
373 */ | |
374 while (!end_detected) | |
375 { | |
376 /* | |
377 * If the length of the next W-parameter is greater than eight bits, | |
378 * use ccd_decodeLong function. For smaller length use the | |
379 * ccd_decodeByte function to extract the W-parameter from the bitstream. | |
380 */ | |
381 lvalue = bf_getBits (act_length, globs); | |
382 w[w_index++] = (short)lvalue; | |
383 | |
384 /* | |
385 * w = 0 is equal to end of list if it is not the w(0) !!! | |
386 * (The case w(0)=0 possible for frequency list, but maybe not for other | |
387 * cases this algorithm is invoked. | |
388 */ | |
389 if (w_index != 1 && w[w_index-1] == 0) | |
390 { | |
391 end_detected = TRUE; | |
392 } | |
393 | |
394 /* End of buffer is equal to end of list. */ | |
395 if (length > act_length) | |
396 { | |
397 length -= act_length; | |
398 } | |
399 else | |
400 { | |
401 end_detected = TRUE; | |
402 } | |
403 | |
404 /* Check if all w parameters of one size are read. */ | |
405 if (--act_counter == 0) | |
406 { | |
407 param++; | |
408 act_length = param->length; | |
409 act_counter = param->count; | |
410 } | |
411 /* End of parameter table */ | |
412 if ((act_length == 0) || (length < act_length)) | |
413 { | |
414 end_detected = TRUE; | |
415 } | |
416 } | |
417 | |
418 /* Add an end identifier. */ | |
419 w[w_index++] = 0; | |
420 } | |
421 #endif /* !RUN_INT_RAM */ |