FreeCalypso > hg > freecalypso-sw
view gsm-fw/ccd/freq_list_com.c @ 700:2913c4fdd34a
top level README: describe the project at a higher level
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Thu, 02 Oct 2014 00:06:50 +0000 |
parents | 970d6199f2c5 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : CCD | Modul : freq_list_com.c +----------------------------------------------------------------------------- | Copyright 2004 Texas Instruments Deutschland GmbH | All rights reserved. | | This file is confidential and a trade secret of Texas | Instruments Deutschland GmbH | The receipt of or possession of this file does not convey | any rights to reproduce or disclose its contents or to | manufacture, use, or sell anything it may describe, in | whole, or in part, without the specific written consent of | Texas Instruments Deutschland GmbH. +----------------------------------------------------------------------------- | Purpose : Definitions of common functions for decoding of types FDD_CI, | TDD_CI and FREQ_LIST. +----------------------------------------------------------------------------- */ #define CDC_FREQ_LIST_COM_C /* * standard definitions like GLOBAL, UCHAR, ERROR etc. */ #include "typedefs.h" #include "header.h" /* * Types and functions for bit access and manipulation */ #include "ccd_globs.h" #include "bitfun.h" /* * Error codes and prototypes of exported functions by CCD */ #include "ccdapi.h" /* * Prototypes of ccd internal functions */ #include "ccd.h" #ifndef RUN_INT_RAM U8 ByteBitMask[]= {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x1}; #endif /* !RUN_INT_RAM */ #ifndef RUN_INT_RAM /* * The following table indicates the number of W-parameters and their * length in bits. A length of zero indicates the end of the table. * For frequency lists the W-parameter in the 1024 range starts from * bit 6 of the information element. */ const T_W_PARAM param_1024[9] = { /* * length count */ 10, 1, 9, 2, 8, 4, 7, 8, 6, 16, 5, 32, 4, 64, 3, 128, 0, 0 }; #endif /* !RUN_INT_RAM */ #ifndef RUN_INT_RAM /* * The following table indicates the number of W-parameters and their * length in bits. A length of zero indicates the end of the table. * For frequency lists the W-parameter in the 512 range starts from * bit 7 of the information element. */ const T_W_PARAM param_512[10] = { /* * length count */ 10, 1, 9, 1, 8, 2, 7, 4, 6, 8, 5, 16, 4, 32, 3, 64, 2, 128, 0, 0 }; #endif /* !RUN_INT_RAM */ #ifndef RUN_INT_RAM /* Attention for RUN_...: static function */ /* +--------------------------------------------------------------------+ | PROJECT : CCD FUNCTION : for_modulo | +--------------------------------------------------------------------+ PURPOSE : A modulo calculation function. The standard C-Operator fails for negative values! (e.g. -4 mod 6 is 2 and not 4). */ /* static */ long for_modulo (long a, long b) { long result; /* Use standard C-Operator for calculation. */ result = a % b; /* Correct the result for negative values. */ if (result < 0) { result += b; } return result; } #endif /* !RUN_INT_RAM */ #ifndef RUN_INT_RAM /* Attention for RUN_...: static function */ /* +--------------------------------------------------------------------+ | PROJECT : CCD FUNCTION : for_smodulo | +--------------------------------------------------------------------+ PURPOSE : Similar to the modulo operator, but 0 smod n is n and not 0. Same problem for negative values with the standard C-Operator. */ static long for_smodulo (long a, long b) { long result; /* Use standard C-Operator for calculation. */ result = a % b; /* Correct the result for negative values. */ if (result < 0) { result += b; } /* Special handling for result equal 0 */ if (result EQ 0) { result = b; } return result; } #endif /* !RUN_INT_RAM */ #ifndef RUN_INT_RAM /* Attention for RUN_...: static function */ /* +--------------------------------------------------------------------+ | PROJECT : CCD FUNCTION : for_get_generation | +--------------------------------------------------------------------+ PURPOSE : The function calculates the greatest power of 2 of the given value. The algorithm simply looks to the position of the highest bit. */ static U16 for_get_generation (U16 value) { int result = 0; int i; /* Check all 16 bit positions. */ for (i = 0; i < 16; i++) { /* If bit is set, store the position. */ if (value & 1) { result = i + 1; } /* Shift value to have the next bit for comparision. */ value = value >> 1; } /* Return the highest position. */ return result; } #endif /* !RUN_INT_RAM */ #ifndef RUN_INT_RAM /* +--------------------------------------------------------------------+ | PROJECT : CCD FUNCTION : cdc_decode_frequencies | +--------------------------------------------------------------------+ PURPOSE : The algorithm is according GSM 4.08 Annex J. It calculates a frequency hopping list from the W-parameter. */ void cdc_decode_frequencies (short original_range, short *w, short offset, U8 callerID, T_CCD_Globs *globs) { short g; short k; short j; short index; short n; short range; U16 channel; U16 bitposition; U8 *BitmapInStruct = globs->pstruct + globs->pstructOffs; U16 first = 0; U16 last = BITOFFSET_LIST; U16 num = 0; BOOL ReadW = TRUE; #ifdef DEBUG_CCD TRACE_CCD (globs, "cdc_decode_frequencies()"); #endif if (callerID != TDD_CI_LIST && w[0] == 0) ReadW = FALSE; for (k = 1; ReadW; k++) { ReadW = (w[k-1] != 0) ? 1 : 0; /* * The next loop follows the tree from child to parent, * from the node of index K to the root (index 1). For each iteration the * node of index INDEX is tackled. The corresponding range is RANGE, and N * is the value of the element in the range defined by the node. * * The data are set to their initial values */ index = k; n = w[index-1]; g = for_get_generation (index); j = (1 << (g-1)); range = original_range / j; while (index > 1) { /* * Due to the assumption that the original range is a power of two minus one, * the range for the parent node can be easily computed, and does not depend * upon whether the current node is a left or right child */ g = for_get_generation (index); j = (1 << (g-1)); range = 2 * range + 1; /* * Let us note J := 2 g-1 , g being the generation of node INDEX. We have J = * GREATEST_POWER_OF_2_LESSER_OR_EQUAL_TO(INDEX). The numbering used in the tree * is such that the nodes of index J to J + J/2 - 1 are left children, and the nodes * of index J/2 to J+J-1 are right children. Hence an easy test to * distinguish left and right children: */ if (2 * index < 3 * j) { /* * The next computation gives the index of the parent node of the node of index * INDEX, for a left child : */ index = index - j / 2; /* * The next formula is the inverse of the renumbering appearing in the encoding * for a left child. It gives the value of the parent node in the range defined * by the grand-parent node: */ n = (short)for_smodulo (n + w[index-1] + (range-1) / 2, range); } else { /* * The next computation gives the index of the parent node of the node of index * INDEX, for a right child : */ index = index - j; /* * The next formula is the inverse of the renumbering appearing in the encoding * for a right child: */ n = (short)for_smodulo (n + w[index-1], range); } } /* * Write the calculated number for non-frequency types. * For TDD_CI and TDD_CI: offset = 0 and original_range = 1023. */ channel = (U16)for_modulo (n+offset, 1024); if (callerID == FDD_CI_LIST || callerID == TDD_CI_LIST) { *(U16*)(globs->pstruct + globs->pstructOffs) = (U16)channel; globs->pstructOffs += 2; } /* Set the calculated channel number for frequency channel list.*/ else { if (channel == 0) { bitposition = 0; } else { bitposition = (U16)(BITOFFSET_LIST - channel); } if (first > bitposition) first = bitposition; if (last < bitposition) last = bitposition; num++; BitmapInStruct[bitposition >> 3] |= ByteBitMask[bitposition & 7]; } } /* For the bitmap type print the helpful information into the structure. */ if (callerID == FREQUENCY_LIST) { *(U16*) (BitmapInStruct - 6) = first; *(U16*) (BitmapInStruct - 6) = last; *(U16*) (BitmapInStruct - 2) = num; } } #endif /* !RUN_INT_RAM */ #ifndef RUN_INT_RAM /* +--------------------------------------------------------------------+ | PROJECT : CCD FUNCTION : cdc_decode_param | +--------------------------------------------------------------------+ PURPOSE : The information element contains a list of W-parameter. The table param indicates how many W-parameter from each length shall be inside. The function converts the bitstream of the W-parameter to an array of W-parameter 16 bit values. */ void cdc_decode_param (const T_W_PARAM *param, short *w, U16 ListLength, T_CCD_Globs *globs) { U8 end_detected = FALSE; U16 w_index = 0; U16 length = ListLength; U16 act_length = param->length; U16 act_counter = param->count; U32 lvalue; #ifdef DEBUG_CCD TRACE_CCD (globs, "cdc_decode_param()"); #endif /* * Decode values in the list until the end of the IE is detected. */ while (!end_detected) { /* * If the length of the next W-parameter is greater than eight bits, * use ccd_decodeLong function. For smaller length use the * ccd_decodeByte function to extract the W-parameter from the bitstream. */ lvalue = bf_getBits (act_length, globs); w[w_index++] = (short)lvalue; /* * w = 0 is equal to end of list if it is not the w(0) !!! * (The case w(0)=0 possible for frequency list, but maybe not for other * cases this algorithm is invoked. */ if (w_index != 1 && w[w_index-1] == 0) { end_detected = TRUE; } /* End of buffer is equal to end of list. */ if (length > act_length) { length -= act_length; } else { end_detected = TRUE; } /* Check if all w parameters of one size are read. */ if (--act_counter == 0) { param++; act_length = param->length; act_counter = param->count; } /* End of parameter table */ if ((act_length == 0) || (length < act_length)) { end_detected = TRUE; } } /* Add an end identifier. */ w[w_index++] = 0; } #endif /* !RUN_INT_RAM */