📄 rake.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 main module | Author: Tommi Makelainen, Nokia Research Center/NIST | Date: February 3, 1999 | | History: | Februrary 3, 1999 Tommi Makelainen | Initial version. | | April 7, 1999 Tommi Makelainen | Updated the whole algorithm. | | May 7, 1999 Tommi Makelainen | Corrected indexing error in finger combining. | | May 27, 1999 Tommi Makelainen | Added extraction of pilot symbols from | input data stream. */#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 *//* ------------ S T A T I C D A T A S T R U C T U R E S ----------- *//* * Allocation list of available rake receivers and the current count. */static enum instance_state rake_alloc_list[MAX_RAKES] = { FREE_INSTANCE, FREE_INSTANCE, FREE_INSTANCE, FREE_INSTANCE, FREE_INSTANCE, FREE_INSTANCE, FREE_INSTANCE };static rake_instance_count = 0;/* * Parameters specific for each rake. */static int init_flags[MAX_RAKES] = { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE };double path_select_level[MAX_RAKES] = { 0 };static finger_type stored_fingers[MAX_RAKES][MAX_FINGERS];static mem_chips_t old_chips[MAX_RAKES];static rake_data_type rake_data[MAX_RAKES];static int pilot_len[MAX_RAKES];static finger_count[MAX_RAKES];/* * Initialization flag for static data structures. */static int general_init_flag = FALSE;/* static mem_chips_t prev_rake_chips; *//* -------------------------------------------------------------------- *//* * Function: wcdma_rake_init * Desc.: Inits rake receiver and returns the allocated * instance number. * * Returns: => 0 allocated instance number, -1 if no free rakes. * * Note: */int wcdma_rake_init( int pilot_length, /* IN: length of pilot in frame (in chips) */ double finger_inc_level, /* IN: finger select threshold */ int nFingers) /* IN: number of fingers to use */{ int i, instance; /* * If first call, initialize static data. */ if (general_init_flag == FALSE) { for (i=0; i < MAX_RAKES; i++) { rake_alloc_list[i] = FREE_INSTANCE; init_flags[i] = TRUE; } /* for */ general_init_flag = TRUE; } /* if general_init_flag */ /* * Find first free instance number. */ instance = -1; for (i=0; i < MAX_RAKES; i++) { if (rake_alloc_list[i] == FREE_INSTANCE) { instance = i; break; } } if (instance == -1) return(-1); /* no free instances */ /* * Store rake specific data. */ init_flags[instance] = TRUE; path_select_level[instance] = finger_inc_level; finger_count[instance] = nFingers; pilot_len[instance] = pilot_length; /* * Update rake allocation list and count. */ rake_alloc_list[instance] = INSTANCE_IN_USE; rake_instance_count++; return(instance);}/* -------------------------------------------------------------------- *//* * Function: wcdma_rake_free * Desc.: Frees one rake reservation. * * Note: */void wcdma_rake_free(int instance){ rake_alloc_list[instance] = FREE_INSTANCE; rake_instance_count--; return;}/* -------------------------------------------------------------------- *//* * Function: wcdma_rake_receiver * Desc.: Collects multipath components of the known signature. * * Note: * Channel impulse response is expected as an input and * is not estimated from the received signal. * Each path is followed until the corresponding channel * tap level goes below the given threshold. */int wcdma_rake_receiver( int instance, /* IN: instance number */ double data[], /* IN: input data symbol vector */ int data_len, /* IN: length of input data vector */ int code[], /* IN: spreading code vector */ int code_len, /* IN: length of spreading code */ int sf, /* IN: Chip/data rate, i.e. spreading factor */ int ch_delays[], /* IN: Channel estimate */ double ch_amplitudes[],/* IN: Channel estimate */ int ch_len, /* IN: Channel estimate */ int *out_len, /* OUT: Number of of output symbols */ int *out_delay, /* OUT: Rx delay to Tx in chips */ double out[]) /* OUT: despreaded output symbol vector */{ int i; static int first_run = TRUE; mem_chips_t *prev_rake_chips; rake_data_type *rake_datum; double inc_level; int nFingers; int pilot_length; int delay, offset; finger_type *fingers; /* * Get data for this rake instance. */ first_run = init_flags[instance]; nFingers = finger_count[instance]; fingers = (finger_type *)&stored_fingers[instance]; inc_level = path_select_level[instance]; pilot_length = pilot_len[instance]; rake_datum = &rake_data[instance]; prev_rake_chips = &old_chips[instance]; /* * Calculate delays for N multipath components from the channel * impulse response. * Check do we have to change the finger allocation. */ wcdma_rake_finger_alloc(instance, first_run, ch_delays, ch_amplitudes, ch_len, code_len, data_len, nFingers, fingers, prev_rake_chips, rake_datum); /* * Despread each multipath component currently in the fingers. * * Each slot contains 'pilot_length' pilot chips in its start. * Below x marks pilot chips and o marks data fields. * * tx slots: /xxooooo\ /xxooooo\ /xxooooo\ /xxooooo\ * rx slots: /xxooooo\ /xxooooo\ /xxooooo\ /xxooooo\ * ^ ^ ^ ^ * sampling interval is ^ * * Due to the simulation strategy tx and rx is simulated * with common clock and sampling interval. That cuts rx slots * which are input to rake in the middle of a slot. * * Despreading ignores pilot chips. */ if (first_run == TRUE) { for (i=0; i < nFingers; i++) { delay = fingers[i].delay; wcdma_rake_symbol_direct(i, data + delay + pilot_length, data_len - delay - pilot_length, code, code_len, fingers+i, prev_rake_chips); fingers[i].old_chips = (data_len - delay - pilot_length) % code_len; } /* for nFingers */ init_flags[instance] = first_run = FALSE; } else { /* if not first_run */ for (i=0; i < nFingers; i++) { delay = data_len - fingers[i].delay; wcdma_rake_symbol_delayed(i, data, data_len, code, code_len, fingers+i, prev_rake_chips); offset = code_len - fingers[i].old_chips; if (offset == code_len) offset = 0; wcdma_rake_symbol_direct(i, data + offset + pilot_length, data_len - offset - pilot_length, code, code_len, fingers+i, prev_rake_chips); } /* for nFingers */ } /* else */ /* * Save unused chips for next round (max one symbol). */ wcdma_rake_finger_memory_save(data, data_len, code_len, prev_rake_chips); /* * Combine the finger outputs to a single despreaded output. * Only fingers above given threshold are used for the estimate. */ wcdma_rake_fingers_combine(fingers, nFingers, out, out_len); return(0);} /* wcdma_rake_receiver *//* -------------------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -