FreeCalypso > hg > fc-magnetite
view src/cs/layer1/cfile/l1_afunc.c @ 702:9394305d4ff5 default tip
etm_audio.c: fix off-by-one error in auw of FIR coefficients
This fix was already made in FC Tourmaline a while back, but it is also
the kind of bugfix that deserves to be backported to Magnetite and
Selenite as well.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 31 Oct 2022 00:14:44 +0000 |
parents | 50a15a54801e |
children |
line wrap: on
line source
/************* Revision Controle System Header ************* * GSM Layer 1 software * L1_AFUNC.C * * Filename l1_afunc.c * Copyright 2003 (C) Texas Instruments * ************* Revision Controle System Header *************/ #define L1_AFUNC_C #include "l1_macro.h" #include "l1_confg.h" #if (CODE_VERSION == SIMULATION) #include <string.h> #include "l1_types.h" #include "sys_types.h" #include "l1_const.h" #include "l1_signa.h" #if TESTMODE #include "l1tm_defty.h" #endif #if (AUDIO_TASK == 1) #include "l1audio_const.h" #include "l1audio_cust.h" #include "l1audio_defty.h" #endif #if (L1_GTT == 1) #include "l1gtt_const.h" #include "l1gtt_defty.h" #endif #if (L1_MIDI == 1) #include "l1midi_defty.h" #endif #if (L1_MP3 == 1) #include "l1mp3_defty.h" #endif //ADDED FOR AAC #if (L1_AAC == 1) #include "l1aac_defty.h" #endif #include "l1_defty.h" #include "cust_os.h" #include "l1_msgty.h" #include "l1_varex.h" #include "l1_proto.h" #include "l1_tabs.h" #include "l1_time.h" #if L1_GPRS #include "l1p_cons.h" #include "l1p_msgt.h" #include "l1p_deft.h" #include "l1p_vare.h" #endif #else #include <string.h> #include "l1_types.h" #include "sys_types.h" #include "l1_const.h" #include "l1_signa.h" #include "l1_time.h" #if TESTMODE #include "l1tm_defty.h" #endif #if (AUDIO_TASK == 1) #include "l1audio_const.h" #include "l1audio_cust.h" #include "l1audio_defty.h" #endif #if (L1_GTT == 1) #include "l1gtt_const.h" #include "l1gtt_defty.h" #endif #if (L1_MP3 == 1) #include "l1mp3_defty.h" #endif #if (L1_MIDI == 1) #include "l1midi_defty.h" #endif //ADDED FOR AAC #if (L1_AAC == 1) #include "l1aac_defty.h" #endif #include "l1_defty.h" #include "cust_os.h" #include "l1_msgty.h" #include "l1_varex.h" #include "l1_proto.h" #include "l1_tabs.h" #if L1_GPRS #include "l1p_cons.h" #include "l1p_msgt.h" #include "l1p_deft.h" #include "l1p_vare.h" #endif #if (GSM_IDLE_RAM > 1) #if (OP_L1_STANDALONE == 1) #include "csmi_simul.h" #else #include "csmi/csmi.h" #endif #endif #endif #if (OP_L1_STANDALONE == 1) #if (ANLG_FAM == 11) #include "bspTwl3029_Madc.h" #endif #endif #if (L1_MADC_ON == 1) #if (OP_L1_STANDALONE == 1) #if (RF_FAM == 61) #include "drp_api.h" #include "l1_rf61.h" #include <string.h> extern T_DRP_SRM_API* drp_srm_api; #endif #if (ANLG_FAM == 11) BspTwl3029_MadcResults l1_madc_results; void l1a_madc_callback(void); #endif #endif #endif //L1_MADC_ON /*-------------------------------------------------------*/ /* l1a_reset_ba_list() */ /*-------------------------------------------------------*/ /* */ /* Description: */ /* ------------ */ /* This function resets the BA list content. */ /* */ /*-------------------------------------------------------*/ void l1a_reset_ba_list() { UWORD8 i; // Rem: this reset function do not touch the "ba_id", "nbr_carrier" and // "radio_freq" fields. //!!! remove this initialization when BA list handling changed for dedic mode if(l1a_l1s_com.mode != I_MODE) { l1a_l1s_com.ba_list.next_to_ctrl = 0; // Carrier for next power measurement control. l1a_l1s_com.ba_list.next_to_read = 0; // Carrier for next power measurement result. l1a_l1s_com.ba_list.first_index = 0; // First BA index measured in current session. } // Reset of "ms_ctrl, ms_ctrl_d, msctrl_dd" is done at L1 startup // and when SYNCHRO task is executed. l1a_l1s_com.ba_list.np_ctrl = 0; // PCH burst number. for(i=0; i<C_BA_PM_MEAS; i++) // 2 measurements / PCH frame... { l1a_l1s_com.ba_list.used_il [i] = l1_config.params.il_min; // IL used in CTRL phase for AGC setting. l1a_l1s_com.ba_list.used_il_d [i] = l1_config.params.il_min; // ... 1 frame delay. l1a_l1s_com.ba_list.used_il_dd[i] = l1_config.params.il_min; // ... 2 frames delay, used in READ phase. l1a_l1s_com.ba_list.used_lna [i] = FALSE; // LNA used in CTRL phase for AGC setting. l1a_l1s_com.ba_list.used_lna_d [i] = FALSE; // ... 1 frame delay. l1a_l1s_com.ba_list.used_lna_dd[i] = FALSE; // ... 2 frames delay, used in READ phase. } for(i=0; i<32+1; i++) { l1a_l1s_com.ba_list.A[i].acc = 0; // Reset IL accumulation. } } /*-------------------------------------------------------*/ /* l1a_reset_full_list() */ /*-------------------------------------------------------*/ /* */ /* Description: */ /* ------------ */ /* This function resets the FULL list content. */ /* */ /*-------------------------------------------------------*/ void l1a_reset_full_list() { UWORD16 i; // Init power measurement multi_session process l1a_l1s_com.full_list.meas_1st_pass_ctrl = 1; // Set 1st pass flag for power measurement session in ctrl. l1a_l1s_com.full_list.meas_1st_pass_read = 1; // Set 1st pass flag for power measurement session in read. l1a_l1s_com.full_list.nbr_sat_carrier_ctrl = 0; // Clear number of saturated carrier in ctrl. l1a_l1s_com.full_list.nbr_sat_carrier_read = 0; // Clear number of saturated carrier in read. // Set global parameters for full list measurement. l1a_l1s_com.full_list.next_to_ctrl = 0; // Set next carrier to control to 1st one. l1a_l1s_com.full_list.next_to_read = 0; // Set next carrier to control to 1st one. // Reset Pipeline // Note: l1a_l1s_com.full_list.ms_ctrl_d is reset at the end of l1_meas_manager() l1a_l1s_com.full_list.ms_ctrl_dd = 0; l1a_l1s_com.full_list.ms_ctrl_d = 0; // Reset the FULL LIST. #if (L1_FF_MULTIBAND == 0) for(i=0; i<l1_config.std.nbmax_carrier; i++) #else for(i=0; i< NBMAX_CARRIER; i++) #endif { l1a_l1s_com.full_list.sat_flag[i] = 0; // Reset sat_flag } #if L1_GPRS // Reset PPCH burst ctrl indication l1pa_l1ps_com.cr_freq_list.pnp_ctrl = 0; #endif } #if ((L1_EOTD == 1) && (L1_EOTD_QBIT_ACC == 1)) /*-------------------------------------------------------*/ /* l1a_add_time_delta() */ /*-------------------------------------------------------*/ /* */ /* Description: */ /* ------------ */ /* This function shifts a given cell timing (given as a */ /* couple [time_alignmt, fn_offset]) by adding */ /* a specified new time_alignmt offset (+ve or -ve */ /* between -4999 and +4999 qb) */ /* to that timing. */ /* */ /*-------------------------------------------------------*/ void l1a_add_time_delta(UWORD32 * time_alignmt, UWORD32 * fn_offset, WORD32 delta) { WORD32 new_time_alignmt = *time_alignmt + delta; UWORD32 new_fn_offset = *fn_offset; if(new_time_alignmt < 0) { new_time_alignmt += TPU_CLOCK_RANGE; new_fn_offset = (new_fn_offset + 1) % MAX_FN; } else if(new_time_alignmt >= TPU_CLOCK_RANGE) { new_time_alignmt -= TPU_CLOCK_RANGE; new_fn_offset = (new_fn_offset - 1 + MAX_FN) % MAX_FN; } *time_alignmt = new_time_alignmt; *fn_offset = new_fn_offset; } /*-------------------------------------------------------*/ /* l1a_compensate_sync_ind() */ /*-------------------------------------------------------*/ /* */ /* Description: */ /* ------------ */ /* Attempts to modify the time_alignmt and fn_offset */ /* fields of an MPHC_NCELL_SYNC_IND message based on */ /* E-OTD cross-correlation information in order to */ /* post-correct the result. This can be used to form a */ /* quater-bit alignment with slow drifting neighbours */ /* */ /*-------------------------------------------------------*/ void l1a_compensate_sync_ind(T_MPHC_NCELL_SYNC_IND * msg) { // This process can only be applied to SBCONF messages // with good SCH decodes and valid EOTD results. // // a_eotd_crosscor [0] [1] [2] [3] [4] [5] [6] [7] [8] // // <------ Peak Range -----> // // As long as the cross-correlation peak lies in the range // [1] to [7] then we can examine the slope of the correlation // points on either side of the peak in order to perform a // positive or negative QB shift. if((msg->sb_flag) && (msg->eotd_data_valid)) { WORD16 peak_index = msg->d_eotd_max - msg->d_eotd_first; if((peak_index >= 1) && (peak_index <= 7)) { UWORD32 a_power[9]; UWORD32 pre_power, post_power, thresh_power; UWORD32 i; WORD32 shift = 0; // Calculate the normalised power of the cross-correlation samples // in a_eotd_crosscor. This could be improved to only calculate // the terms for [peak_index-1] [peak_index] [peak_index+1] if // the algorithm proves viable in the long term. // Normalised power[i] = real[i]^2 + imag[i]^2 for(i=0; i<9; ++i) { // // Awkward looking code to square values as our compiler / assembler // gets the following construct wrong. Very strange... // // UWORD32 real = ... // real *= real; <-- Assembler allocates registers incorrectly here // UWORD32 real = msg->a_eotd_crosscor[2*i] * msg->a_eotd_crosscor[2*i]; UWORD32 imag = msg->a_eotd_crosscor[(2*i)+1] * msg->a_eotd_crosscor[(2*i)+1]; // Sum of the squares... a_power[i] = real + imag; } // By inspection of practical examples, it appears that (peak power/3) // is a good threshold on which to compare the shape of the slope. thresh_power = a_power[peak_index] / 3; pre_power = a_power[peak_index-1]; post_power = a_power[peak_index+1]; // Decision on whether the gradient of the slope of the crosscor points // on either side of the peak is large enough to cause a (max) +/- 1QB shift // to the time_alignmt field. if( (pre_power < thresh_power) && (post_power > thresh_power) ) { // Right skew on the cross corrrelation - shift time_alignmt // to be one greater shift = 1; } else if ( (pre_power > thresh_power) && (post_power < thresh_power) ) { // Left skew on the cross correlation - shift time_alignmt // to be one less shift = -1; } l1a_add_time_delta( &(msg->time_alignmt), &(msg->fn_offset), shift ); } } } #endif /*-------------------------------------------------------*/ /* l1a_add_time_for_nb() */ /*-------------------------------------------------------*/ /* */ /* Description: */ /* ------------ */ /* This function shift a given cell timing (given as a */ /* couple [time_alignmt, fn_offset]) by adding */ /* "SB_MARGIN - NB_MARGIN" */ /* to that timing. */ /* */ /*-------------------------------------------------------*/ void l1a_add_time_for_nb(UWORD32 *time_alignmt, UWORD32 *fn_offset) { // Add "SB_MARGIN - NB_MARGIN" qbit to "fn_offset" and "time_alignmt". // Pay attention to the modulos. *time_alignmt += (SB_MARGIN - NB_MARGIN); if(*time_alignmt >= TPU_CLOCK_RANGE) { *time_alignmt -= TPU_CLOCK_RANGE; *fn_offset = (*fn_offset + MAX_FN - 1) % MAX_FN; } } /*-------------------------------------------------------*/ /* l1a_add_timeslot() */ /*-------------------------------------------------------*/ /* */ /* Description: */ /* ------------ */ /* This function shift a given cell timing (given as a */ /* couple [time_alignmt, fn_offset]) by adding a number */ /* of TIMESLOT (given as "tn") to that timing. */ /* */ /*-------------------------------------------------------*/ void l1a_add_timeslot(UWORD32 *time_alignmt, UWORD32 *fn_offset, UWORD8 tn) { // Add "tn" timeslot to "fn_offset" and "time_alignmt". // Pay attention to the modulos. *time_alignmt += tn * BP_DURATION; if(*time_alignmt >= TPU_CLOCK_RANGE) { *time_alignmt -= TPU_CLOCK_RANGE; *fn_offset = (*fn_offset + MAX_FN - 1) % MAX_FN; } } /*-------------------------------------------------------*/ /* l1a_sub_time_for_nb() */ /*-------------------------------------------------------*/ /* */ /* Description: */ /* ------------ */ /* This function shift a given cell timing (given as a */ /* couple [time_alignmt, fn_offset]) by substacting */ /* "SB_MARGIN - NB_MARGIN" */ /* to that timing. */ /* */ /*-------------------------------------------------------*/ void l1a_sub_time_for_nb(UWORD32 *time_alignmt, UWORD32 *fn_offset) { WORD32 new_time_alignmt; // Sub "SB_MARGIN - NB_MARGIN" qbit to "fn_offset" and "time_alignmt". // Pay attention to the modulos. new_time_alignmt = *time_alignmt - (SB_MARGIN - NB_MARGIN); if(new_time_alignmt < 0) { new_time_alignmt += TPU_CLOCK_RANGE; *fn_offset = (*fn_offset + 1) % MAX_FN; } *time_alignmt = new_time_alignmt; } /*-------------------------------------------------------*/ /* l1a_sub_timeslot() */ /*-------------------------------------------------------*/ /* */ /* Description: */ /* ------------ */ /* This function shift a given cell timing (given as a */ /* couple [time_alignmt, fn_offset]) by substracting a */ /* number of TIMESLOT (given as "tn") to that timing. */ /* */ /*-------------------------------------------------------*/ void l1a_sub_timeslot(UWORD32 *time_alignmt, UWORD32 *fn_offset, UWORD8 tn) { WORD32 new_time_alignmt; // Sub "tn" timeslot to "fn_offset" and "time_alignmt". // Pay attention to the modulos. new_time_alignmt = *time_alignmt - (tn * BP_DURATION); if(new_time_alignmt < 0) { new_time_alignmt += TPU_CLOCK_RANGE; *fn_offset = (*fn_offset + 1) % MAX_FN; } *time_alignmt = new_time_alignmt; } /*-------------------------------------------------------*/ /* l1a_correct_timing() */ /*-------------------------------------------------------*/ /* */ /* Description: */ /* ------------ */ /* */ /*-------------------------------------------------------*/ #if (L1_12NEIGH == 1) void l1a_correct_timing (UWORD8 neigh_id,UWORD32 time_alignmt,UWORD32 fn_offset) { // Save timing information in case of future handovers. l1a_l1s_com.nsync.list[neigh_id].time_alignmt_mem = time_alignmt; l1a_l1s_com.nsync.list[neigh_id].fn_offset_mem = fn_offset; // Sub the serving cell timeslot number to the Neigh./Serving timing // difference to format it for L1S use. l1a_sub_timeslot(&time_alignmt, &fn_offset, l1a_l1s_com.dl_tn); l1a_sub_time_for_nb(&time_alignmt, &fn_offset); // Save neighbor information in the neighbor confirmation cell structure. l1a_l1s_com.nsync.list[neigh_id].time_alignmt = time_alignmt; l1a_l1s_com.nsync.list[neigh_id].fn_offset = fn_offset; } #endif /*-------------------------------------------------------*/ /* l1a_compute_Eotd_data() */ /*-------------------------------------------------------*/ /* */ /* Description: */ /* ------------ */ /* */ /*-------------------------------------------------------*/ #if ((L1_12NEIGH ==1) && (L1_EOTD == 1)) void l1a_compute_Eotd_data( UWORD8 *first_scell, UWORD8 neigh_id, UWORD32 SignalCode, xSignalHeaderRec *msg) { WORD32 ta_sb_neigh; UWORD32 fn_sb_neigh; WORD16 d_eotd_first; WORD32 toa_correction; UWORD32 timetag; // SB case ..... if (SignalCode == L1C_SB_INFO) { fn_sb_neigh = ((T_L1C_SB_INFO *)(msg->SigP))->fn_sb_neigh; d_eotd_first= ((T_L1C_SB_INFO *)(msg->SigP))->d_eotd_first; toa_correction = ((T_L1C_SB_INFO *)(msg->SigP))->toa_correction; } // SBCONF case ..... else { fn_sb_neigh = ((T_L1C_SBCONF_INFO *)(msg->SigP))->fn_sb_neigh; d_eotd_first= ((T_L1C_SBCONF_INFO *)(msg->SigP))->d_eotd_first; toa_correction = ((T_L1C_SBCONF_INFO *)(msg->SigP))->toa_correction; } // compute the true Serving/Neighbor time difference. // 1) update time_alignmt with (23bit - d_eotd_first) delta // 2) Add the serving cell timeslot number to the Serving/Neighbor time difference. ta_sb_neigh = l1a_l1s_com.nsync.list[neigh_id].time_alignmt; ta_sb_neigh += (d_eotd_first - (23))*4 + (l1a_l1s_com.dl_tn * 625); // for Serving cell, timetag reference is 0 if (*first_scell == TRUE) { l1a_l1s_com.nsync.fn_sb_serv = fn_sb_neigh; l1a_l1s_com.nsync.ta_sb_serv = ta_sb_neigh; timetag = 0; } else { UWORD32 delta_fn; WORD32 delta_qbit; delta_fn = (fn_sb_neigh - l1a_l1s_com.nsync.fn_sb_serv + MAX_FN)%MAX_FN; delta_qbit = ta_sb_neigh - l1a_l1s_com.nsync.ta_sb_serv; // Set timetag timetag = (delta_fn*5000) + (WORD32)(delta_qbit) + toa_correction; #if (CODE_VERSION == SIMULATION) #if (TRACE_TYPE==5) ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->delta_fn = delta_fn; ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->delta_qbit = delta_qbit; #endif #endif } // Set timetag ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->timetag = timetag; } #endif /*-------------------------------------------------------*/ /* l1a_get_free_dedic_set() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : */ /*-------------------------------------------------------*/ T_DEDIC_SET *l1a_get_free_dedic_set() { T_DEDIC_SET *fset; UWORD8 i; // Get free set pointer. if(l1a_l1s_com.dedic_set.aset == &(l1a_l1s_com.dedic_set.set[0])) fset = &(l1a_l1s_com.dedic_set.set[1]); else fset = &(l1a_l1s_com.dedic_set.set[0]); // Clear free set. fset->achan_ptr = NULL; fset->chan1.desc.channel_type = INVALID_CHANNEL; fset->chan1.desc_bef_sti.channel_type = INVALID_CHANNEL; fset->chan2.desc.channel_type = INVALID_CHANNEL; fset->chan2.desc_bef_sti.channel_type = INVALID_CHANNEL; fset->ma.alist_ptr = NULL; fset->ma.freq_list.rf_chan_cnt = 0; fset->ma.freq_list_bef_sti.rf_chan_cnt = 0; // Starting time. fset->serv_sti_fn = -1; fset->neig_sti_fn = -1; // Frequency redefinition flag. fset->freq_redef_flag = FALSE; // Timing Advance fset->timing_advance = 0; fset->new_timing_advance = 0; // TXPWR fset->new_target_txpwr = NO_TXPWR; // Cell Information l1a_reset_cell_info(&(fset->cell_desc)); // Cipering. fset->a5mode = 0; // Ciphering OFF. // Clear O&M test variables. fset->dai_mode = 0; // No DAI test. fset->chan1.tch_loop = 0; // No TCH loop on chan1. fset->chan2.tch_loop = 0; // No TCH loop on chan2. // For handover... fset->ho_acc = 0; fset->ho_acc_to_send = 0; fset->t3124 = 0; #if ((REL99 == 1) && (FF_BHO == 1)) // For blind handover... fset->report_time_diff = FALSE; fset->nci = FALSE; fset->report_time_diff = FALSE; fset->real_time_difference = 0; fset->HO_SignalCode = 0; #endif // Reset DPAGC fifo for(i=0;i<DPAGC_FIFO_LEN;i++) { fset->G_all[i] = 200; fset->G_DTX[i] = 200; } // Reset DTX_ALLOWED field. fset->dtx_allowed = FALSE; #if IDS // clear ids_mode: default value = speech mode fset->ids_mode = 0; #endif #if (AMR == 1) // Clear the AMR ver 1.0 network settings fset->amr_configuration.noise_suppression_bit = FALSE; fset->amr_configuration.initial_codec_mode_indicator = FALSE; fset->amr_configuration.initial_codec_mode = 0; fset->amr_configuration.active_codec_set = 0; fset->amr_configuration.threshold[0] = 0; fset->amr_configuration.threshold[1] = 0; fset->amr_configuration.threshold[2] = 0; fset->amr_configuration.hysteresis[0] = 0; fset->amr_configuration.hysteresis[1] = 0; fset->amr_configuration.hysteresis[2] = 0; fset->cmip = C_AMR_CMIP_DEFAULT; #endif return(fset); } /*-------------------------------------------------------*/ /* l1a_fill_bef_sti_param() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : */ /*-------------------------------------------------------*/ void l1a_fill_bef_sti_param(T_DEDIC_SET *set_ptr, BOOL start_time_present) { if(start_time_present == TRUE) // There is a STARTING TIME field... { if((set_ptr->ma.freq_list_bef_sti.rf_chan_cnt != 0) || (set_ptr->chan1.desc_bef_sti.channel_type != INVALID_CHANNEL) || (set_ptr->chan2.desc_bef_sti.channel_type != INVALID_CHANNEL)) // There is at least one "bef_sti" parameter given for this channel. // Other empty parameters must be filled with the according "AFTER STARTING TIME" parameters. { // Fill "chan1.desc_bef_sti" if(set_ptr->chan1.desc_bef_sti.channel_type == INVALID_CHANNEL) set_ptr->chan1.desc_bef_sti = set_ptr->chan1.desc; // Fill "chan2.desc_bef_sti" if(set_ptr->chan2.desc_bef_sti.channel_type == INVALID_CHANNEL) set_ptr->chan2.desc_bef_sti = set_ptr->chan2.desc; // Fill "freq_list_bef_sti" if(set_ptr->ma.freq_list_bef_sti.rf_chan_cnt == 0) set_ptr->ma.freq_list_bef_sti = set_ptr->ma.freq_list; } } } /*-------------------------------------------------------*/ /* l1a_decode_starting_time() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : */ /*-------------------------------------------------------*/ WORD32 l1a_decode_starting_time(T_STARTING_TIME coded_starting_time) { WORD32 starting_time; if(coded_starting_time.start_time_present == TRUE ) // A starting time is present. // --------------------------- { WORD32 tp1 = coded_starting_time.start_time.n32; WORD32 t2 = coded_starting_time.start_time.n26; WORD32 t3 = coded_starting_time.start_time.n51; // Compute STI. starting_time = 51*((26 + t3 - t2) % 26) + t3 + (51*26*tp1) ; } else { starting_time = -1; } return(starting_time); } /*-------------------------------------------------------*/ /* l1a_reset_cell_info() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : */ /*-------------------------------------------------------*/ void l1a_reset_cell_info(T_CELL_INFO *cell_info) { cell_info->bsic = 0; cell_info->fn_offset = 0; cell_info->time_alignmt = 0; cell_info->meas.acc = 0; cell_info->meas.nbr_meas = 0; cell_info->attempt_count = 0; cell_info->si_bit_map = 0; cell_info->traffic_meas.input_level = l1_config.params.il_min; cell_info->traffic_meas_beacon.input_level = l1_config.params.il_min; cell_info->traffic_meas.lna_off = FALSE; cell_info->traffic_meas_beacon.lna_off = FALSE; cell_info->buff_beacon[0] = cell_info->buff_beacon[1] = cell_info->buff_beacon[2] = cell_info->buff_beacon[3] = l1_config.params.il_min; #if L1_GPRS cell_info->transfer_meas.input_level = l1_config.params.il_min; cell_info->transfer_meas.lna_off = FALSE; cell_info->pb = 0; #endif } /*-------------------------------------------------------*/ /* l1a_send_confirmation() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : */ /*-------------------------------------------------------*/ void l1a_send_confirmation(UWORD32 SignalCode, UWORD8 queue_type) { xSignalHeaderRec *msg; msg = os_alloc_sig(0); DEBUGMSG(status,NU_ALLOC_ERR) msg->SignalCode = (int)SignalCode; #if (TRACE_TYPE==1) || (TRACE_TYPE==4) l1_trace_message(msg); #endif #if (OP_L1_STANDALONE == 1) os_send_sig(msg, queue_type); #else os_send_sig(msg, ((T_ENUM_OS_QUEUE)queue_type)); //omaps00090550 #endif DEBUGMSG(status,NU_SEND_QUEUE_ERR) } /*-------------------------------------------------------*/ /* l1a_send_result() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : */ /*-------------------------------------------------------*/ void l1a_send_result(UWORD32 SignalCode, xSignalHeaderRec *msg, UWORD8 queue) { // Set flag to avoid the FREE(msg) in L1ASYNC. l1a.l1_msg_forwarded = TRUE; msg->SignalCode = (int)SignalCode; // May not be necessary -> to check #if (GSM_IDLE_RAM > 1) if (!READ_TRAFFIC_CONT_STATE) { CSMI_TrafficControllerOn(); } #endif #if (TRACE_TYPE==1) || (TRACE_TYPE==4) l1_trace_message(msg); #endif #if (OP_L1_STANDALONE == 1) os_send_sig(msg, queue); #else os_send_sig(msg, ((T_ENUM_OS_QUEUE)queue)); //omaps00090550 #endif DEBUGMSG(status,NU_SEND_QUEUE_ERR) } /*-------------------------------------------------------*/ /* l1a_encode_rxqual() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : */ /*-------------------------------------------------------*/ UWORD8 l1a_encode_rxqual (UWORD32 inlevel) { enum qual_thr { thr_0_2 = 4, thr_0_4 = 8, thr_0_8 = 16, thr_1_6 = 32, thr_3_2 = 64, thr_6_4 = 128, thr_12_8 = 256 }; UWORD8 rxqual; if (inlevel < thr_0_2) rxqual = 0; else if (inlevel < thr_0_4) rxqual = 1; else if (inlevel < thr_0_8) rxqual = 2; else if (inlevel < thr_1_6) rxqual = 3; else if (inlevel < thr_3_2) rxqual = 4; else if (inlevel < thr_6_4) rxqual = 5; else if (inlevel < thr_12_8) rxqual = 6; else rxqual = 7; return((UWORD8) rxqual); } /*-------------------------------------------------------*/ /* l1a_report_failling_ncell_sync() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : */ /*-------------------------------------------------------*/ void l1a_report_failling_ncell_sync(UWORD32 SignalCode, UWORD8 neigh_id) { xSignalHeaderRec *msg; // Send MPHC_NCELL_SYNC_IND message to L3 with a FAILLURE indication. msg = os_alloc_sig(sizeof(T_MPHC_NCELL_SYNC_IND)); DEBUGMSG(status,NU_ALLOC_ERR) msg->SignalCode = SignalCode; ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->sb_flag = FALSE; ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->radio_freq = l1a_l1s_com.nsync.list[neigh_id].radio_freq; ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->bsic = 0; ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->fn_offset = 0; ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->time_alignmt = 0; // For trace/debug only ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->neigh_id = neigh_id; #if (TRACE_TYPE==1) || (TRACE_TYPE==4) l1_trace_message(msg); #endif os_send_sig(msg, RRM1_QUEUE); DEBUGMSG(status,NU_SEND_QUEUE_ERR) } /*-------------------------------------------------------*/ /* l1a_clip_txpwr() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : */ /*-------------------------------------------------------*/ #if (L1_FF_MULTIBAND == 0) UWORD8 l1a_clip_txpwr (UWORD8 supplied_txpwr, UWORD16 radio_freq) { #define txpwr_to_compare(pwr) ((pwr<=l1_config.std.txpwr_turning_point)? pwr+32:pwr) switch(l1_config.std.id) { case GSM: case GSM_E: { // Clip LOW according to powerclass_band1. if ( supplied_txpwr < MIN_TXPWR_GSM[l1a_l1s_com.powerclass_band1]) return(MIN_TXPWR_GSM[l1a_l1s_com.powerclass_band1]); // Clip HIGH according to GSM spec. 05.05. if ( supplied_txpwr > l1_config.std.max_txpwr_band1) return(l1_config.std.max_txpwr_band1); } break; case PCS1900: { // Clip LOW according to powerclass_band1. if ( txpwr_to_compare(supplied_txpwr) < txpwr_to_compare(MIN_TXPWR_PCS[l1a_l1s_com.powerclass_band1]) ) return(MIN_TXPWR_PCS[l1a_l1s_com.powerclass_band1]); // Clip HIGH according to GSM spec. 05.05. if ( txpwr_to_compare(supplied_txpwr) > txpwr_to_compare(l1_config.std.max_txpwr_band1) ) return(l1_config.std.max_txpwr_band1); } break; case DCS1800: { // Clip LOW according to powerclass_band1. if ( txpwr_to_compare(supplied_txpwr) < txpwr_to_compare(MIN_TXPWR_DCS[l1a_l1s_com.powerclass_band1]) ) return(MIN_TXPWR_DCS[l1a_l1s_com.powerclass_band1]); // Clip HIGH according to GSM spec. 05.05. if ( txpwr_to_compare(supplied_txpwr) > txpwr_to_compare(l1_config.std.max_txpwr_band1) ) return(l1_config.std.max_txpwr_band1); } break; case GSM850: { // Clip LOW according to powerclass_band1. if ( txpwr_to_compare(supplied_txpwr) < txpwr_to_compare(MIN_TXPWR_GSM850[l1a_l1s_com.powerclass_band1]) ) return(MIN_TXPWR_GSM850[l1a_l1s_com.powerclass_band1]); // Clip HIGH according to GSM spec. 05.05. if ( txpwr_to_compare(supplied_txpwr) > txpwr_to_compare(l1_config.std.max_txpwr_band1) ) return(l1_config.std.max_txpwr_band1); } break; case DUAL: case DUALEXT: { // Test which Band is used: GSM or DCS 1800 if (radio_freq >= l1_config.std.first_radio_freq_band2) { // Clip LOW according to powerclass_band1. if ( txpwr_to_compare(supplied_txpwr) < txpwr_to_compare(MIN_TXPWR_DCS[l1a_l1s_com.powerclass_band2]) ) return(MIN_TXPWR_DCS[l1a_l1s_com.powerclass_band2]); // Clip HIGH according to GSM spec. 05.05. if ( txpwr_to_compare(supplied_txpwr) > txpwr_to_compare(l1_config.std.max_txpwr_band2) ) return(l1_config.std.max_txpwr_band2); } else { // Clip LOW according to powerclass_band1. if ( supplied_txpwr < MIN_TXPWR_GSM[l1a_l1s_com.powerclass_band1]) return(MIN_TXPWR_GSM[l1a_l1s_com.powerclass_band1]); // Clip HIGH according to GSM spec. 05.05. if ( supplied_txpwr > l1_config.std.max_txpwr_band1) return(l1_config.std.max_txpwr_band1); } } break; case DUAL_US: { // Test which Band is used: GSM 850 or PCS1900 if (radio_freq >= l1_config.std.first_radio_freq_band2) { // Clip LOW according to powerclass_band1. if ( txpwr_to_compare(supplied_txpwr) < txpwr_to_compare(MIN_TXPWR_PCS[l1a_l1s_com.powerclass_band2]) ) return(MIN_TXPWR_PCS[l1a_l1s_com.powerclass_band2]); // Clip HIGH according to GSM spec. 05.05. if ( txpwr_to_compare(supplied_txpwr) > txpwr_to_compare(l1_config.std.max_txpwr_band2) ) return(l1_config.std.max_txpwr_band2); } else { // Clip LOW according to powerclass_band1. if ( supplied_txpwr < MIN_TXPWR_GSM850[l1a_l1s_com.powerclass_band1]) return(MIN_TXPWR_GSM850[l1a_l1s_com.powerclass_band1]); // Clip HIGH according to GSM spec. 05.05. if ( supplied_txpwr > l1_config.std.max_txpwr_band1) return(l1_config.std.max_txpwr_band1); } } break; default: // should never occur { return(supplied_txpwr); } // omaps00090550 break; } return(supplied_txpwr); } #else /*L1_FF_MULTIBAND = 1 below */ UWORD8 l1a_clip_txpwr (UWORD8 supplied_txpwr, UWORD16 radio_freq) { UWORD8 physical_band_id = 0; physical_band_id = l1_multiband_radio_freq_convert_into_physical_band_id(radio_freq); #define txpwr_to_compare(pwr) ((pwr<= multiband_rf[physical_band_id].tx_turning_point)? pwr+32:pwr) switch(multiband_rf[physical_band_id].gsm_band_identifier) { case RF_GSM900: { // Clip LOW according to powerclass_band1. if ( supplied_txpwr < MIN_TXPWR_GSM[l1a_l1s_com.powerclass[physical_band_id]]) return(MIN_TXPWR_GSM[l1a_l1s_com.powerclass[physical_band_id]]); // Clip HIGH according to GSM spec. 05.05. if ( supplied_txpwr > multiband_rf[physical_band_id].max_txpwr) return(multiband_rf[physical_band_id].max_txpwr); break; }/*case GSM900*/ case RF_PCS1900: { // Clip LOW according to powerclass_band1. if ( txpwr_to_compare(supplied_txpwr) < txpwr_to_compare(MIN_TXPWR_PCS[l1a_l1s_com.powerclass[physical_band_id]]) ) return(MIN_TXPWR_PCS[l1a_l1s_com.powerclass[physical_band_id]]); // Clip HIGH according to GSM spec. 05.05. if ( txpwr_to_compare(supplied_txpwr) > txpwr_to_compare(multiband_rf[physical_band_id].max_txpwr) ) return(multiband_rf[physical_band_id].max_txpwr); break; }/*case PCS1900*/ case RF_DCS1800: { // Clip LOW according to powerclass_band1. if ( txpwr_to_compare(supplied_txpwr) < txpwr_to_compare(MIN_TXPWR_DCS[l1a_l1s_com.powerclass[physical_band_id]]) ) return(MIN_TXPWR_DCS[l1a_l1s_com.powerclass[physical_band_id]]); // Clip HIGH according to GSM spec. 05.05. if ( txpwr_to_compare(supplied_txpwr) > txpwr_to_compare(multiband_rf[physical_band_id].max_txpwr) ) return(multiband_rf[physical_band_id].max_txpwr); break; }/*case DCS1800*/ case RF_GSM850: { // Clip LOW according to powerclass_band1. if ( txpwr_to_compare(supplied_txpwr) < txpwr_to_compare(MIN_TXPWR_GSM850[l1a_l1s_com.powerclass[physical_band_id]]) ) return(MIN_TXPWR_GSM850[l1a_l1s_com.powerclass[physical_band_id]]); // Clip HIGH according to GSM spec. 05.05. if ( txpwr_to_compare(supplied_txpwr) > txpwr_to_compare(multiband_rf[physical_band_id].max_txpwr) ) return(multiband_rf[physical_band_id].max_txpwr); break; }/*case GSM850*/ default: // should never occur { l1_multiband_error_handler(); return(supplied_txpwr); break; } /*default*/ }/*switch(multiband_rfphysical_band_id].gsm_band_identifier)*/ return(supplied_txpwr); } #endif /*L1_FF_MULTIBAND */ //MADC #if (L1_MADC_ON == 1) #if (OP_L1_STANDALONE == 1) #if (ANLG_FAM == 11) void l1a_madc_callback(void) { char str[40]; xSignalHeaderRec *adc_msg; UWORD16 *adc_result; UWORD16 *madc_results; volatile UWORD16 *drp_temp_results; #if (RF_FAM == 61) drp_temp_results =(volatile UWORD16 *) (&drp_srm_api->inout.temperature.output); //omaps00090550 #endif #if 0 sprintf(str, "Temp Measure %x ", drp_temp_results); //L1_trace_string ("Temp Meas\n"); L1_trace_string(str); #endif #if 0 int i; adc_msg = os_alloc_sig(sizeof(BspTwl3029_MadcResults) + sizeof(UWORD16)); adc_result = &((BspTwl3029_MadcResults*)(adc_msg->SigP))->adc1; madc_results =& l1_madc_results.adc1; //TEMP_MEAS: DRP #if (RF_FAM == 61) drp_temp_results =& (drp_srm_api->inout.temperature.output); #endif //copy the measured values into the the message structure. memcpy(adc_result,madc_results,11*sizeof(UWORD16));//11 madc adc_result[11] = *drp_temp_results; // 1 temp meas /* for (i=0;i<11;i++) adc_result[i] = madc_results[i]; */ //Send the message adc_msg->SignalCode = CST_ADC_RESULT; os_send_sig(adc_msg, RRM1_QUEUE); #endif } #endif // ANLG_FAM == 11 #endif //OP_L1_STANDALONE #endif // L1_MADC_ON //==============================================================================================