📄 rake_supp.c
字号:
/* | | Copyright disclaimer: | This software was developed at the National Institute of Standards | and Technology by employees of the Federal Government in the course | of their official duties. Pursuant to title 17 Section 105 of the | United States Code this software is not subject to copyright | protection and is in the public domain. | | We would appreciate acknowledgement if the software is used. |*//* | Project: WCDMA simulation environment | Module: RAKE receiver functions. | Author: Tommi Makelainen, Nokia Research Center | Date: February 3, 1999 | | History: | Februrary 3, 1999 Tommi Makelainen | Initial version. | | April 7, 1999 Tommi Makelainen | Updated the whole algorithm. | | May 10, 1999 Tommi Makelainen | Corrected indexing error in finger combining. | | May 20, 1999 Tommi Makelainen | Corrected indexing error in spreading of | delayed chips. | If channel changes, finger allocation | now changes allocation after FAST_FADE_TIME | slots. | */#include <stdio.h>#include <stdlib.h>#include <math.h>#include "config_wcdma.h"#include "spreading.h"#include "rake.h"#ifndef TRUE#define TRUE 1#define FALSE 0#endif /* TRUE */#define UNKNOWN 1#define EXISTING 2#define NEW 3/* -------------------------------------------------------------------- *//* * Function: wcdma_rake_finger_alloc * Desc.: Selects 'finger_count' strongest multipath components * from the channel impulse response. * If the fingers are already allocated, then an individual * finger must be FAST_FADE_TIME below the threshold * FINGER_ALLOC_THRESHOLD. * * Note: * Channel impulse response is expected as an input and * is not estimated from the received signal. */int wcdma_rake_finger_alloc( int instance, /* IN: instance number */ int init_flag, /* IN: init flag, TRUE = init */ int channel_delays[], /* IN: channel estimate */ double channel_amplitudes[], /* IN: channel estimate */ int channel_len, /* IN: channel estimate length */ int code_len, /* IN: length of spreading code */ int data_len, /* IN: length of input data vector */ int nFingers, /* IN: number_fingers in use */ finger_type *fingers, /* IN/OUT: finger data */ mem_chips_t *prev_rake_chips, /* IN: data of old chips */ rake_data_type *misc_data) /* OUT: rake related data */{ int candidates[MAX_CHANNEL_LEN]; int used_tap_candidates[MAX_CHANNEL_LEN]; int tmp_candidate; int i, j, k, tap_status, stable_taps; /* * Mark all candidates with an initial value. */ for (i=0; i < MAX_CHANNEL_LEN; i++) candidates[i] = i; for (i=0; i < MAX_CHANNEL_LEN; i++) used_tap_candidates[i] = FALSE; tap_status = UNKNOWN; /* * Search through the channel estimate and select * 'finger_count' strongest taps to 'candidates' vector. * The candidate vector is sorted in descending order. */ for (i=0; i < channel_len; i++) { for (j=i+1; j < channel_len; j++) { if (channel_amplitudes[ candidates[i] ] < channel_amplitudes[ candidates[j] ] ) { /* * Swap indexes i and j. */ tmp_candidate = candidates[j]; candidates[j] = candidates[i]; candidates[i] = tmp_candidate; } /* if */ } /* for j */ } /* for i */ /* * Compare current candidates with the existing finger allocation. * If a finger has been FAST_FADE_TIME frames time below the threshold * FINGER_ALLOC_THRESHOLD, change allocation of the finger. * If there is no tap on the previous delay, but there is a new tap * within CHANNEL_TAP_DRIFT chips, assume that the multipath component * has drifted in time. * Fingers are allocated in descending amplitude order, i.e. strongest * multipath component first. */ if (init_flag != TRUE) { stable_taps = 0; for (i=0, j=0; i < nFingers; i++) { tap_status = UNKNOWN; j = 0; /* * If finger not previously allocated, skip out. */ if (fingers[i].status == -1) continue; /* * Search the current finger delay match in new channel estimate. * Match is found only if there is a tap on the finger delay * and tap amplitude in channel response is above * FINGER_ALLOC_THRESHOLD. */ for (k=0; k < channel_len; k++) { if ( (fingers[i].delay == channel_delays[ candidates[j] ]) && (fingers[i].amplitude > FINGER_ALLOC_THRESHOLD) ) { tap_status = EXISTING; fingers[i].amplitude = channel_amplitudes[candidates[j]]; used_tap_candidates[j] = TRUE; stable_taps++; } j++; } /* for k over channel_len */ /* * Tap delay allocated to current finger is not available * in the current channel impulse response. */ if (tap_status == UNKNOWN) {#ifdef TESTING printf("instance %d, finger %d, channel changes, status %d\n", instance, i, fingers[i].status);#endif /* TESTING */ if (fingers[i].status < FAST_FADE_TIME) { fingers[i].status += 1; stable_taps++; } else { /* * tap delay in finger has not been present * in channel response for FAST_FADE_TIME * slots, release the current allocation. */ fingers[i].status = -1;#ifdef TESTING printf("instance %d, %d finger released\n", instance, i);#endif /* TESTING */ } /* else */ } /* if tap_status */ } /* for nFingers*/ /* * Chech if channel response has changed. */ if (stable_taps < nFingers) { /* allocate released finger to a new tap */ for (i=0; i < nFingers; i++) { if (fingers[i].status == -1) { /* * Search strongest not allocated channel tap. */ for (j=0; j < channel_len; j++) { if (used_tap_candidates[j] == FALSE) { /* * Test that new channel tap candidate * has amplitude that is above * FINGER_ALLOC_THRESHOLD. * If not, keep the previous allocation * even though it has exceeded * FAST_FADE_TIME. */ if (channel_amplitudes[ candidates[j] ] < FINGER_ALLOC_THRESHOLD) { fingers[i].status = FAST_FADE_TIME - 1; break; }#ifdef TESTING printf("instance %d,chan index %d, new allocation for finger %d, delay %d\n", instance, j, i, channel_delays[candidates[j]]);#endif /* TESTING */ fingers[i].status = 0; fingers[i].delay = channel_delays[ candidates[j] ]; fingers[i].amplitude = channel_amplitudes[ candidates[j] ]; fingers[i].weight = 1.0; fingers[i].fill_index = 0; fingers[i].combine_index = 0; used_tap_candidates[j] = TRUE; fingers[i].nOutputs = 0; fingers[i].old_chips = (data_len - fingers[i].delay) % code_len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -