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 */ |
