doc/Modem-configs update: we now have both Standard Modem and VPM
functionality choices
line source
+ − /************* Revision Controle System Header *************
+ − * GSM Layer 1 software
+ − * L1_CMPLX.C
+ − *
+ − * Filename l1_cmplx.c
+ − * Copyright 2003 (C) Texas Instruments
+ − *
+ − ************* Revision Controle System Header *************/
+ −
+ − #define L1_CMPLX_C
+ −
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+ −
+ − #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_time.h"
+ − #include "l1_signa.h"
+ − #include <l1_trace.h>
+ −
+ − #if TESTMODE
+ − #include "l1tm_defty.h"
+ − #endif
+ − #if (AUDIO_TASK == 1)
+ − #include "l1audio_const.h"
+ − #include "l1audio_cust.h"
+ − #include "l1audio_signa.h"
+ − #include "l1audio_defty.h"
+ − #include "l1audio_msgty.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_mftab.h"
+ − #include "l1_tabs.h"
+ − #include "l1_ver.h"
+ − #if L2_L3_SIMUL
+ − #include "l2_l3.h"
+ − #include "hw_debug.h"
+ − #endif
+ −
+ − #if L1_GPRS
+ − #include "l1p_cons.h"
+ − #include "l1p_msgt.h"
+ − #include "l1p_deft.h"
+ − #include "l1p_vare.h"
+ − #include "l1p_sign.h"
+ − #endif
+ −
+ − #include "sim_cons.h"
+ − #include "sim_def.h"
+ − extern T_hw FAR hw;
+ −
+ − #else
+ − #include "abb.h"
+ − #include <string.h>
+ − #include "l1_types.h"
+ − #include "sys_types.h"
+ − #include "l1_const.h"
+ − #include "l1_time.h"
+ − #include "l1_signa.h"
+ − #if TESTMODE
+ − #include "l1tm_defty.h"
+ − #if (RF_FAM == 60)
+ − #include "pld.h"
+ − #endif
+ − #endif
+ − #if (AUDIO_TASK == 1)
+ − #include "l1audio_const.h"
+ − #include "l1audio_cust.h"
+ − #include "l1audio_signa.h"
+ − #include "l1audio_defty.h"
+ − #include "l1audio_msgty.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_mftab.h"
+ − #include "l1_tabs.h"
+ − #include "l1_ver.h"
+ − #include "l1_trace.h"
+ − #include "l1_ctl.h"
+ − #if L2_L3_SIMUL
+ − #include "l2_l3.h"
+ − #include "hw_debug.h"
+ − #include "l2_simul.h"
+ − #endif
+ −
+ − #if L1_GPRS
+ − #include "l1p_cons.h"
+ − #include "l1p_msgt.h"
+ − #include "l1p_deft.h"
+ − #include "l1p_vare.h"
+ − #include "l1p_sign.h"
+ − #endif
+ − #endif
+ −
+ − #if(RF_FAM == 61)
+ − #include "l1_rf61.h"
+ − #include "tpudrv61.h"
+ − #endif
+ − #include "l1_ctl.h"
+ −
+ − #if W_A_DSP1
+ − extern UWORD8 old_sacch_DSP_bug;
+ − #endif
+ −
+ − #if TESTMODE
+ − #include "l1tm_msgty.h"
+ − #include "l1tm_signa.h"
+ − #include "l1tm_varex.h"
+ − void l1tm_fill_burst (UWORD16 pattern, UWORD16 *TM_ul_data);
+ − #if (ANLG_FAM != 11)
+ − void ABB_Write_Uplink_Data(SYS_UWORD16 *TM_ul_data);
+ − #else
+ − // TODO
+ − #endif
+ − #endif
+ −
+ − #if ((TRACE_TYPE==2) || (TRACE_TYPE==3))
+ − extern void L1_trace_string(char *s);
+ − extern void L1_trace_char (char s);
+ − #endif
+ −
+ − #if (GSM_IDLE_RAM != 0)
+ − #if (OP_L1_STANDALONE == 1)
+ − #include "csmi_simul.h"
+ − #else
+ − #include "csmi/sleep.h"
+ − #endif
+ − #endif
+ −
+ − #if (RF_FAM == 61)
+ − #include "l1_rf61.h"
+ − #if (DRP_FW_EXT==1)
+ − #include "l1_drp_inc.h"
+ − #else
+ − #include "drp_drive.h"
+ − #endif
+ − #endif
+ −
+ − /*-------------------------------------------------------*/
+ − /* Prototypes of external functions used in this file. */
+ − /*-------------------------------------------------------*/
+ − void l1dmacro_synchro (UWORD32 when, UWORD32 value);
+ −
+ − void l1dmacro_offset (UWORD32 offset_value, WORD32 relative_time);
+ − void l1dmacro_rx_synth (UWORD16 arfcn);
+ − void l1dmacro_agc (UWORD16 arfcn,WORD8 gain, UWORD8 lna
+ − #if (RF_FAM == 61)
+ − ,UWORD8 if_ctl
+ − #endif
+ − );
+ − void l1dmacro_rx_nb (UWORD16 arfcn);
+ − void l1dmacro_afc (UWORD16 afc_value, UWORD8 win_id);
+ − void l1dmacro_adc_read_rx (void);
+ − #if (CODE_VERSION != SIMULATION)
+ − #if (L1_MADC_ON ==1)
+ − void l1dmacro_adc_read_rx_cs_mode0(void);
+ − #endif
+ − #endif
+ −
+ − #if (RF_FAM != 61)
+ − void l1dtpu_serv_rx_nb (UWORD16 radio_freq, WORD8 agc, UWORD8 lna_off,
+ − UWORD32 synchro_serv,UWORD32 new_offset,BOOL change_offset, UWORD8 adc_active);
+ − #endif
+ −
+ − #if (RF_FAM == 61)
+ − void l1dtpu_serv_rx_nb (UWORD16 radio_freq, WORD8 agc, UWORD8 lna_off,
+ − UWORD32 synchro_serv,UWORD32 new_offset,BOOL change_offset,
+ − UWORD8 adc_active, UWORD8 csf_filter_choice, UWORD8 if_ctl
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,UWORD8 saic_flag
+ − #endif /* NEW_SNR_THRESHOLD*/
+ − );
+ − #endif /* RF_FAM == 61*/
+ −
+ − void l1ddsp_meas_read (UWORD8 nbmeas, UWORD8 *pm);
+ −
+ − #if L1_GPRS
+ − void l1pddsp_synchro (UWORD8 switch_mode, UWORD8 camp_timeslot);
+ − void l1pddsp_load_bcchn_task (UWORD8 tsq,UWORD16 radio_freq);
+ − void l1pddsp_meas_ctrl (UWORD8 nbmeas, UWORD8 pm_pos);
+ − void l1pddsp_meas_read (UWORD8 nbmeas, UWORD8 *a_pm);
+ − #if FF_L1_IT_DSP_USF
+ − void l1pddsp_idle_rx_nb (UWORD8 burst_nb, UWORD8 tsq, UWORD16 radio_freq,
+ − UWORD8 timeslot_no, BOOL ptcch_dl, BOOL usf_interrupt);
+ − #else
+ − void l1pddsp_idle_rx_nb (UWORD8 burst_nb, UWORD8 tsq, UWORD16 radio_freq,
+ − UWORD8 timeslot_no, BOOL ptcch_dl);
+ − #endif
+ − #endif
+ −
+ − #if (RF_FAM == 61)
+ − void cust_get_if_dco_ctl_algo (UWORD16* dco_algo_ctl, UWORD8* if_ctl,
+ − UWORD8 input_level_flag, UWORD8 input_level, UWORD16 radio_freq, UWORD8 if_threshold);
+ − #endif
+ −
+ −
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+ −
+ − extern UWORD16 toa_tab[4];
+ −
+ −
+ − #if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM !=0)) // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM enabled
+ − //#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_START // KEEP IN EXTERNAL MEM otherwise
+ − UWORD16 toa_tab[4];
+ − //#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END
+ − #endif
+ −
+ −
+ − #if TESTMODE
+ − UWORD16 TM_ul_data[16]; //Uplink data to be stored into Omega Uplink buffer
+ − #endif
+ − #if ((REL99 == 1) && (FF_BHO == 1))
+ − void l1dtpu_neig_fbsb(UWORD16 radio_freq, WORD8 agc, UWORD8 lna_off); // Blind handover
+ − #endif
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_hwtest() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* task HWTEST. This function check the checksum of the */
+ − /* DSP. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.dsp_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/DSP */
+ − /* interface. This is used mainly to swap then the */
+ − /* com. page at the end of a control frame. */
+ − /* -> set CTRL_TEST bit in the register. */
+ − /*-------------------------------------------------------*/
+ − void l1s_ctrl_hwtest(UWORD8 task, UWORD8 param2)
+ − {
+ − // Flag DSP programmation.
+ − // ************************
+ − l1ddsp_load_monit_task(DSP_TASK_CODE[task],0);
+ −
+ − // Set "CTRL_TEST" flag in the controle flag register.
+ − l1s.dsp_ctrl_reg |= CTRL_TEST;
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_read_hwtest() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* task HWTEST. This function read the checksum of the */
+ − /* DSP. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1a_l1s_com.l1s_en_task" */
+ − /* L1S task enable bit register. */
+ − /* -> disable HWTEST task. */
+ − /* */
+ − /* "l1s.task_status[HWTEST].current_status" */
+ − /* current task status for HWTEST task. */
+ − /* -> disactivate HWTEST task. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_read_hwtest(UWORD8 task, UWORD8 param2)
+ − {
+ − #if (TRACE_TYPE==2) || (TRACE_TYPE==3)//OMAPS00090550
+ − UWORD32 flash_type = 0;
+ − #endif
+ − xSignalHeaderRec *msg;
+ −
+ − #if (CODE_VERSION != SIMULATION)
+ − #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)
+ − l1s.version.dsp_code_version = l1s_dsp_com.dsp_ndb_ptr->d_version_number1;
+ − l1s.version.dsp_checksum = (UWORD16) (l1s_dsp_com.dsp_db_r_ptr->a_pm[1] & 0xffff);
+ − l1s.version.dsp_patch_version = l1s_dsp_com.dsp_ndb_ptr->d_version_number2;
+ − #else
+ − l1s.version.dsp_code_version = (UWORD16) (l1s_dsp_com.dsp_db_r_ptr->a_pm[0] & 0xffff);
+ − l1s.version.dsp_checksum = (UWORD16) (l1s_dsp_com.dsp_db_r_ptr->a_pm[1] & 0xffff);
+ − //l1s.version.dsp_patch_version = (UWORD16) (l1s_dsp_com.dsp_db_r_ptr->a_pm[2] & 0xffff);
+ − l1s.version.dsp_patch_version = (UWORD32) *((API *) SC_CHKSUM_VER);
+ − //NOTE: dsp_patch_version is duplicated in d_version_number
+ − #endif
+ − #endif // NOT_SIMULATION
+ −
+ − // send L1_INIT_HW_CON to L1A...
+ − msg = os_alloc_sig(sizeof(T_TST_TEST_HW_CON));
+ − DEBUGMSG(status,NU_ALLOC_ERR)
+ − msg->SignalCode = L1_TEST_HW_INFO;
+ −
+ − // added for the new naming convention
+ − ((T_TST_TEST_HW_CON*)(msg->SigP))->dsp_code_version = l1s.version.dsp_code_version;
+ − ((T_TST_TEST_HW_CON*)(msg->SigP))->dsp_checksum = l1s.version.dsp_checksum;
+ − ((T_TST_TEST_HW_CON*)(msg->SigP))->dsp_patch_version = l1s.version.dsp_patch_version;
+ − ((T_TST_TEST_HW_CON*)(msg->SigP))->mcu_tcs_program_release = l1s.version.mcu_tcs_program_release;
+ − ((T_TST_TEST_HW_CON*)(msg->SigP))->mcu_tcs_official = l1s.version.mcu_tcs_official;
+ − ((T_TST_TEST_HW_CON*)(msg->SigP))->mcu_tcs_internal = l1s.version.mcu_tcs_internal;
+ −
+ − os_send_sig(msg, L1C1_QUEUE);
+ −
+ − DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+ −
+ − #if (TRACE_TYPE==2) || (TRACE_TYPE==3)
+ − uart_trace_checksum(flash_type);
+ − #endif
+ −
+ − // HWTEST task is completed, make it INACTIVE.
+ − // It is a 1 shot task, it must be also disabled in L1S.
+ − l1s.task_status[task].current_status = INACTIVE;
+ − l1a_l1s_com.l1s_en_task[HWTEST] = TASK_DISABLED;
+ −
+ − // Flag the use of the MCU/DSP dual page read interface.
+ − // ******************************************************
+ −
+ − // Set flag used to change the read page at the end of "l1_synch" only.
+ − l1s_dsp_com.dsp_r_page_used = TRUE;
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_new_synchro() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* task SYNCHRO. This function mainly adapts the L1/TPU */
+ − /* timebase to a new setting. This new setting can come */
+ − /* from a timeslot change or a full change of serving */
+ − /* cell. This change is a big discontinuity, it requires */
+ − /* some global variable reset. Here is a summary of the */
+ − /* execution: */
+ − /* */
+ − /* - Traces for debug. */
+ − /* - Disables the L1S task SYNCHRO (SYNCHRO is 1 shot) */
+ − /* and make it inactive (current status set to */
+ − /* INACTIVE). */
+ − /* - Compute timeshift. */
+ − /* - Program serving cell fine timeshift for TPU. */
+ − /* - Execute serving cell frame number timeshift. */
+ − /* - Flag TPU programmation. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1a_l1s_com.tn_difference" */
+ − /* timeslot difference between new and old setting. */
+ − /* This is used when timeshift is due to a change of */
+ − /* timeslot but on the same serving cell. */
+ − /* -> reset to 0. */
+ − /* */
+ − /* "l1a_l1s_com.Scell_inf.time_alignmt" */
+ − /* fine time difference between current setting and */
+ − /* new setting to achieve. */
+ − /* -> reset to 0. */
+ − /* */
+ − /* "l1a_l1s_com.Scell_inf.fn_offset" */
+ − /* frame number offset between current setting and new */
+ − /* setting to achieve. */
+ − /* -> reset to 0. */
+ − /* */
+ − /* "l1s.tpu_offset" */
+ − /* value for SYNCHRO and OFFSET register in the TPU */
+ − /* for current serving cell setting. */
+ − /* -> set to the new setting. */
+ − /* */
+ − /* "l1a_l1s_com.l1s_en_task" */
+ − /* L1S task enable bit register. */
+ − /* -> disable SYNCHRO task. */
+ − /* */
+ − /* "l1s.task_status[SYNCHRO].current_status" */
+ − /* current task status for SYNCHRO task. */
+ − /* -> disactivate SYNCHRO task. */
+ − /* */
+ − /* "l1s.actual_time, l1s.next_time" */
+ − /* frame number and derived numbers for current frame */
+ − /* and next frame. */
+ − /* -> update to new setting. */
+ − /* */
+ − /* "l1s.tpu_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/TPU */
+ − /* interface. This is used mainly to swap then the */
+ − /* com. page at the end of a control frame. */
+ − /* -> set CTRL_SYNC bit in the register. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_new_synchro(UWORD8 param1, UWORD8 param2)
+ − {
+ − WORD32 offset;
+ − UWORD32 tpu_offset_shift;
+ − T_CELL_INFO *sptr = &(l1a_l1s_com.Scell_info);
+ −
+ − // Traces for debug mainly used during L1 simulation.
+ − // ***************************************************
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_NEW_SYNCHRO, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_tpu(dltsk_trace[SYNCHRO].name);
+ − #endif
+ −
+ − // Disable SYNCHRO task.
+ − // **********************
+ −
+ − // SYNCHRO task is a one shot task enabled by L1A and
+ − // disables after its execution in L1S. Here is the disabling.
+ − l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_DISABLED;
+ − l1s.task_status[SYNCHRO].current_status = INACTIVE;
+ −
+ − #if 0 /* FreeCalypso TCS211 reconstruction */
+ − #if L1_GPRS
+ − //Change of mode when synchro is executed when switching from idle to transfer
+ − //In this case, PDTCH task has been enabled in transfer mode manager, but the mode is still not PACKET_TRANSFER_MODE
+ − if((l1a_l1s_com.l1s_en_task[PDTCH] == TASK_ENABLED) && (l1a_l1s_com.mode != PACKET_TRANSFER_MODE))
+ − l1a_l1s_com.mode = PACKET_TRANSFER_MODE;
+ − #endif
+ − #endif
+ −
+ − // Compute timeshift.
+ − // *******************
+ −
+ − if(l1a_l1s_com.tn_difference < 0)
+ − // "tn_difference" field is not 0 only when the new serving cell is the same
+ − // as the old one. Therefore, we are just changing the timeslot.
+ − // If the new timeslot if lower than the old one then the serving FN must
+ − // be incremented by 1. To do so, we use the "fn_offset" field which is
+ − // loaded with "1".
+ − {
+ − sptr->fn_offset += 1;
+ − l1a_l1s_com.tn_difference += 8;
+ − }
+ −
+ − // update the TPU with the new TOA if necessary
+ − l1ctl_update_TPU_with_toa();
+ −
+ − // Manage shifting value for TPU offset register...
+ − // if staying on the same serving cell but changing the RX timeslot (CCCH_GROUP or timeslot),
+ − // then the "timeslot difference" between old and new configuration is given in "tn_difference",
+ − // else "tn_difference" must contain 0.
+ − tpu_offset_shift = (sptr->time_alignmt) + (l1a_l1s_com.tn_difference * BP_DURATION);
+ −
+ − // Clear "timeslot difference" parameter.
+ − l1a_l1s_com.tn_difference = 0;
+ −
+ − // Get FN difference between actual synchro and the one we are going to switch to.
+ − // The switch (slide of OFFSET and REG_COM_INT) is performed at the time "OFFSET - epsilon".
+ − // If "tpu_offset_shift" is greater than "OFFSET - epsilon (called SWITCH_TIME)" then
+ − // the next interrupt is going to occur very soon after the switch, and new FN comes directly
+ − // from current FN + the "fn_offset" (minus 1 since FN has just been incremented). Else 1 frame
+ − // is missed and new FN comes from "fn_offset + 1" (minus 1 since FN has just been incremented).
+ − offset = sptr->fn_offset - 1;
+ − if(tpu_offset_shift <= SWITCH_TIME) offset++;
+ − #if L1_FF_WA_OMAPS00099442
+ − if(l1a_l1s_com.change_tpu_offset_flag == TRUE){
+ − l1s.tpu_offset = (l1s.tpu_offset + (TPU_CLOCK_RANGE >> 1) ) % TPU_CLOCK_RANGE;
+ − l1a_l1s_com.change_tpu_offset_flag = FALSE;
+ − }
+ − #endif
+ −
+ − // Shift "tpu_offset" accordingly to the computed "tpu_offset_shift" value.
+ − // Rem: "%" is required since the result value can be greater than 2*TPU_CLOCK_RANGE.
+ − l1s.tpu_offset = (l1s.tpu_offset + tpu_offset_shift) % TPU_CLOCK_RANGE;
+ −
+ − // Program serving cell fine timeshift for TPU.
+ − // *********************************************
+ −
+ − // Store the fine time shifting program in the MCU/TPU com.
+ − l1dmacro_synchro(SWITCH_TIME, l1s.tpu_offset);
+ −
+ − // Execute serving cell frame number timeshift.
+ − // *********************************************
+ −
+ − // Slide frame numbers and derived numbers to jump on new setting.
+ − l1s_increment_time(&(l1s.actual_time), offset); // Update actual_time.
+ −
+ − l1s.next_time = l1s.actual_time;
+ − l1s_increment_time(&(l1s.next_time), 1); // Next time is actual_time + 1
+ −
+ − #if L1_GPRS
+ − l1s.next_plus_time = l1s.next_time;
+ − l1s_increment_time(&(l1s.next_plus_time), 1); // Next_plus time is next_time + 1
+ − #endif
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − trace_fct(CST_L1S_ADJUST_TIME, (UWORD32)(-1));//OMAPS00090550
+ − #endif
+ −
+ − #if (TOA_ALGO == 2)
+ − // Fix in case of handovers and Test Mode
+ − l1s.toa_var.toa_update_fn = l1s.toa_var.toa_update_fn + offset;
+ − if(l1s.toa_var.toa_update_fn >= MAX_FN)
+ − {
+ − l1s.toa_var.toa_update_fn-= MAX_FN;
+ − }
+ − #endif
+ −
+ −
+ −
+ − // the FN was changed: it could have an impact on the gauging algorithm
+ − //Nina modify to save power, not forbid deep sleep, only force gauging in next paging
+ − /* FreeCalypso Frankenstein: see l1_async.c regarding Nina's change */
+ − #define NINA_ADDED 0
+ − #if NINA_ADDED
+ − if(l1s.force_gauging_next_paging_due_to_CCHR != 1)
+ − #endif
+ − {
+ − l1s.pw_mgr.enough_gaug = FALSE; // forbid Deep sleep until next gauging
+ − }
+ −
+ −
+ − // Clear Serving offset and bob.
+ − sptr->fn_offset = 0;
+ − sptr->time_alignmt = 0;
+ −
+ − // Flag TPU programmation.
+ − // ************************
+ −
+ − // Set "CTRL_SYNC" flag in the controle flag register.
+ − l1s.tpu_ctrl_reg |= CTRL_SYNC;
+ −
+ − #if (CODE_VERSION == SIMULATION)
+ − si_scheduling(MPHC_SCELL_NBCCH_REQ, NULL, TRUE);
+ − si_scheduling(MPHC_SCELL_EBCCH_REQ, NULL, TRUE);
+ − #endif
+ −
+ − #if TESTMODE
+ − // Continuous mode: if we are in continuous mode: return to the no continuous mode.
+ − if ((l1_config.TestMode) && (l1_config.tmode.rf_params.tmode_continuous == TM_CONTINUOUS))
+ − l1_config.tmode.rf_params.tmode_continuous = TM_NO_CONTINUOUS;
+ − #endif
+ −
+ − #if L1_GPRS
+ − // Signals the GSM->GPRS or GPRS->GSM switch to the DSP.
+ − // ******************************************************
+ − l1pddsp_synchro(l1a_l1s_com.dsp_scheduler_mode, l1a_l1s_com.dl_tn);
+ −
+ − // Flag DSP programmation.
+ − // Set "CTRL_SYNC" flag in the controle flag register.
+ − l1s.dsp_ctrl_reg |= CTRL_SYNC;
+ − #endif
+ −
+ − #if (CODE_VERSION == SIMULATION)
+ − si_scheduling(MPHC_SCELL_NBCCH_REQ, NULL, TRUE);
+ − si_scheduling(MPHC_SCELL_EBCCH_REQ, NULL, TRUE);
+ − #endif
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_ADC() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* task ADC. This function program the L1/TPU in order */
+ − /* to perform an ADC measurement in CS_MODE0 */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_ctrl_ADC(UWORD8 param1, UWORD8 param2)
+ − {
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_ADC, (UWORD32)(-1));//OMAPS00090550
+ − #endif
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+ − #endif
+ −
+ − // In CS_MODE0, MPHC_RXLEV_REQ is not received periodically. In case network is not found,
+ − //the period between 2 MPHC_RXLEV_REQ increases and can be as high as 360 seconds (Max Value)
+ − // To enable MADC periodically, the function l1dmacro_adc_read_rx_cs_mode0; is called
+ − #if (CODE_VERSION != SIMULATION)
+ − #if (L1_MADC_ON ==1)
+ − if (l1a_l1s_com.mode == CS_MODE0)
+ − l1dmacro_adc_read_rx_cs_mode0();
+ − else
+ − l1dmacro_adc_read_rx(); // ADC performed into a rx scenario to have BULON and BULENA signals off so maintaining
+ − // low power consumption on ABB
+ − #else
+ − l1dmacro_adc_read_rx(); // ADC performed into a rx scenario to have BULON and BULENA signals off so maintaining
+ − // low power consumption on ABB
+ − #endif // End of L1_MADC_ON == 1
+ − #else
+ − l1dmacro_adc_read_rx(); // ADC performed into a rx scenario to have BULON and BULENA signals off so maintaining
+ − // low power consumption on ABB
+ − #endif
+ −
+ −
+ − l1s.task_status[ADC_CSMODE0].current_status = INACTIVE;
+ −
+ − if (l1a_l1s_com.adc_mode & ADC_NEXT_CS_MODE0) // performe ADC only one time
+ − {
+ − l1a_l1s_com.adc_mode &= ADC_MASK_RESET_IDLE; // reset in order to have only one ADC measurement in CS_MODE0
+ − l1a_l1s_com.l1s_en_task[ADC_CSMODE0] = TASK_DISABLED; // disable the ADC task in case of one shot
+ − }
+ −
+ − // Set "CTRL_MS" flag in the controle flag register.
+ − l1s.tpu_ctrl_reg |= CTRL_ADC;
+ − }
+ −
+ − #if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM !=0)) // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM enabled
+ − //#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_START // KEEP IN EXTERNAL MEM otherwise
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_abort() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* task ABORT. When the L1S merge manager routine, */
+ − /* "l1s_merge_manager()", finds a conflict between a */
+ − /* running task and a pending task, it can come to */
+ − /* aborting the running one to start executing the */
+ − /* pending. Here is the routine which resets the comm. */
+ − /* between the MCU and the DSP and TPU. The DSP is also */
+ − /* signaled to abort any ongoing task. Here is a summary */
+ − /* of the execution: */
+ − /* */
+ − /* - Traces for debug. */
+ − /* - Reset MCU/DSP and MCU/TPU communications. */
+ − /* - Signals the ABORT process to the DSP. */
+ − /* - Flag DSP programmation. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1s.tpu_offset" */
+ − /* OFFSET/SYNCHRO registers value for current serving */
+ − /* cell setting. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.dsp_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/DSP */
+ − /* interface. This is used mainly to swap then the */
+ − /* com. page at the end of a control frame. */
+ − /* -> set CTRL_ABORT bit in the register. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_abort(UWORD8 param1, UWORD8 param2)
+ − {
+ − // Traces for debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE==5)
+ − trace_fct(CST_L1S_ABORT, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+ − trace_fct(CST_L1S_ABORT_W0_R0, (UWORD32)(-1));//OMAPS00090550
+ − #endif
+ −
+ − #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+ − if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_L1S_DEBUG)
+ − Trace_L1s_Abort(trace_info.abort_task);
+ − #endif
+ −
+ − // Reset MCU/DSP and MCU/TPU communications.
+ − // ******************************************
+ −
+ − // Reset Hardware...
+ − // Set "tpu_reset_bit" to 1.
+ − // Reset DSP write/read page.
+ − // Reset communication pointers.
+ − // Immediate Reload offset with Serving one.
+ − l1d_reset_hw(l1s.tpu_offset);
+ −
+ − l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+ −
+ − // Signals the ABORT process to the DSP.
+ − // **************************************
+ −
+ − // Set "b_abort" to TRUE, dsp will reset current and pending tasks.
+ − l1s_dsp_com.dsp_db_w_ptr->d_ctrl_system |= (1 << B_TASK_ABORT);
+ −
+ −
+ − // Tasks are aborted on DSP side => forbid measurements during ABORT
+ − l1s.forbid_meas = 1;
+ −
+ − // Flag DSP programmation.
+ − // ************************
+ −
+ − // Set "CTRL_ABORT" flag in the controle flag register.
+ − l1s.dsp_ctrl_reg |= CTRL_ABORT;
+ − #if (FF_L1_FAST_DECODING == 1)
+ − /* Reset fast decoding */
+ − l1a_apihisr_com.fast_decoding.status = C_FAST_DECODING_NONE;
+ − l1a_apihisr_com.fast_decoding.contiguous_decoding = FALSE;
+ − #endif /* #if (FF_L1_FAST_DECODING == 1) */
+ − }
+ −
+ − //#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END
+ − #endif
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_msagc() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* tasks: BCCHN,FBNEW,SB1,SB2,SBCONF. This function is */
+ − /* the control function for making a power measurement */
+ − /* for refreshing the AGC for those tasks. It programs */
+ − /* the DSP and the TPU for making 1 measurement in the */
+ − /* next frame. Here is a summary of the execution: */
+ − /* */
+ − /* - If SEMAPHORE(task) is low. */
+ − /* - Get the cell information structure. */
+ − /* - Traces and debug. */
+ − /* - Programs DSP for measurement task. */
+ − /* - Programs TPU for measurement task. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* BCCHN, BCCH Neighbor reading task. */
+ − /* FBNEW, Frequency Burst detection task in Idle mode. */
+ − /* SB1, Synchro Burst reading task in Idle mode. */
+ − /* SB2, Synchro Burst detection task in Idle mode. */
+ − /* SBCONF, Synchro Burst confirmation task in Idle */
+ − /* mode. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1s.afc" */
+ − /* current AFC value to be applied for FBNEW and SB2 */
+ − /* tasks in Cell Selection only. */
+ − /* */
+ − /* "l1a_l1s_com.task_param" */
+ − /* task semaphore bit register. Used to skip this */
+ − /* control if L1A has changed or is changing some of */
+ − /* the task parameters. */
+ − /* */
+ − /* "l1a_l1s_com.Ncell_info.bcch" */
+ − /* "l1a_l1s_com.Ncell_info.acquis" */
+ − /* "l1a_l1s_com.Ncell_info.acquis" */
+ − /* "l1a_l1s_com.Ncell_info.conf" */
+ − /* cell information structure used for BCCHN,FBNEW, */
+ − /* SB1/SB2,SBCONF respectively. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.tpu_win" */
+ − /* each frame is composed with a maximum of 3 */
+ − /* working/TPU windows (typically RX/TX/PW). This is */
+ − /* a counter used to count the number of windows */
+ − /* used. */
+ − /* -> incremented. */
+ − /* */
+ − /* "l1s.tpu_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/TPU */
+ − /* interface. This is used mainly to swap then the */
+ − /* com. page at the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /* "l1s.dsp_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/DSP */
+ − /* interface. This is used mainly to swap then the */
+ − /* com. page at the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_ctrl_msagc(UWORD8 task, UWORD8 param2)
+ − {
+ − #if (RF_FAM == 61)
+ − UWORD16 dco_algo_ctl_pw = 0;
+ − UWORD8 if_ctl = 0;
+ − //OMAPS00090550 UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+ − #endif
+ −
+ − if(!(l1a_l1s_com.task_param[task]))
+ − // Check the task semaphore. The control body is executed only
+ − // when the task semaphore is 0. This semaphore can be set to
+ − // 1 whenever L1A makes some changes to the task parameters.
+ − {
+ − T_NCELL_SINGLE *cell_info_ptr = NULL;
+ − #if (L1_GPRS)
+ − T_NCELL_SINGLE pbcchn_cell_info;
+ − #endif
+ − #if ((REL99 == 1) && (FF_BHO == 1))
+ − T_NCELL_SINGLE bho_cell_info;
+ − #endif
+ −
+ − // Get the cell information structure.
+ − // ************************************
+ −
+ − switch(task)
+ − {
+ − case BCCHN: cell_info_ptr = &l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_norm];break;
+ − case BCCHN_TOP:cell_info_ptr = &l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_top];break;
+ − case FBNEW: cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id]; break;
+ − case SB2: cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sb_id]; break;
+ − case SBCONF: cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sbconf_id];break;
+ −
+ − #if ((REL99 == 1) && (FF_BHO == 1))
+ − case FBSB:
+ − {
+ − cell_info_ptr = &bho_cell_info;
+ − bho_cell_info.radio_freq = l1a_l1s_com.nsync_fbsb.radio_freq;
+ − bho_cell_info.fn_offset = l1a_l1s_com.nsync_fbsb.fn_offset;
+ − }
+ − break;
+ − #endif
+ −
+ − #if (L1_GPRS)
+ − case PBCCHN_IDLE:
+ − {
+ − cell_info_ptr = &pbcchn_cell_info;
+ − pbcchn_cell_info.radio_freq = l1pa_l1ps_com.pbcchn.bcch_carrier;
+ − pbcchn_cell_info.fn_offset = l1pa_l1ps_com.pbcchn.fn_offset;
+ − }
+ − break;
+ − #endif
+ − default: return;
+ − }
+ −
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_MSAGC, cell_info_ptr->radio_freq);
+ − #endif
+ −
+ − l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+ −
+ −
+ − // Programs DSP for measurement task.
+ − // ***********************************
+ −
+ − // Dsp pgm... (2 measurement).
+ − #if L1_GPRS
+ − switch (l1a_l1s_com.dsp_scheduler_mode)
+ − {
+ − case GPRS_SCHEDULER:
+ − {
+ − l1pddsp_meas_ctrl(2,0);
+ − } break;
+ −
+ − case GSM_SCHEDULER:
+ − {
+ − l1ddsp_load_monit_task(2, 0);
+ − } break;
+ − }
+ − #else
+ − l1ddsp_load_monit_task(2, 0);
+ − #endif
+ −
+ − #if (RF_FAM == 61)
+ − #if (PWMEAS_IF_MODE_FORCE == 0)
+ − cust_get_if_dco_ctl_algo (&dco_algo_ctl_pw, &if_ctl,
+ − (UWORD8) L1_IL_INVALID, 0,
+ − cell_info_ptr->radio_freq,C_IF_ZERO_LOW_THRESHOLD_GSM);//OMAPS00090550
+ − #else
+ − if_ctl = IF_120KHZ_DSP;
+ − dco_algo_ctl_pw = DCO_IF_0KHZ;
+ − #endif
+ −
+ − // Duplicate the outcome of DCO control as there are 2 PM
+ − dco_algo_ctl_pw = (((dco_algo_ctl_pw<<2) & 0x0C) | (dco_algo_ctl_pw & 0x03)); // 0000ZLZL
+ − l1ddsp_load_dco_ctl_algo_pw(dco_algo_ctl_pw);
+ − #endif
+ −
+ − // Programs TPU for measurement task.
+ − // ***********************************
+ − // tpu pgm: measurement only.
+ − if (task == FBNEW)
+ − {
+ − l1dtpu_meas(cell_info_ptr->radio_freq,
+ − l1_config.params.high_agc,
+ − 0, // 0 is set for lna_off = 0
+ − l1s.tpu_win,
+ − l1s.tpu_offset, INACTIVE
+ − #if(RF_FAM == 61)
+ − ,L1_AFC_NONE
+ − ,if_ctl
+ − #endif
+ − );
+ − }
+ − else
+ − {
+ − l1dtpu_meas(cell_info_ptr->radio_freq,
+ − l1_config.params.high_agc,
+ − 0, // 0 is set for lna_off = 0
+ − l1s.tpu_win,
+ − l1s.tpu_offset, INACTIVE
+ − #if(RF_FAM == 61)
+ − ,L1_AFC_SCRIPT_MODE
+ − ,if_ctl
+ − #endif
+ − );
+ − }
+ −
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET_NEIGH)
+ − buffer_trace(4, l1s.actual_time.fn, cell_info_ptr->radio_freq,
+ − cell_info_ptr->fn_offset, l1s.tpu_win);
+ − #endif
+ − #endif
+ −
+ − if (task == FBNEW)
+ − {
+ − // Increment tpu window identifier.
+ − l1s.tpu_win += (l1_config.params.rx_synth_load_split + PWR_LOAD);
+ −
+ − // tpu pgm: measurement only.
+ − l1dtpu_meas(cell_info_ptr->radio_freq,
+ − l1_config.params.low_agc,
+ − 0, // 0 is set for lna_off = 0
+ − l1s.tpu_win,
+ − l1s.tpu_offset,
+ − INACTIVE
+ − #if(RF_FAM == 61)
+ − ,L1_AFC_SCRIPT_MODE
+ − ,if_ctl
+ − #endif
+ − );
+ − }
+ − else
+ − {
+ − // Increment tpu window identifier.
+ − l1s.tpu_win += (l1_config.params.rx_synth_load_split + PWR_LOAD);
+ −
+ − // tpu pgm: measurement only.
+ − l1dtpu_meas(cell_info_ptr->radio_freq,
+ − l1_config.params.low_agc,
+ − 0, // 0 is set for lna_off = 0
+ − l1s.tpu_win,
+ − l1s.tpu_offset,
+ − INACTIVE
+ − #if(RF_FAM == 61)
+ − ,L1_AFC_SCRIPT_MODE
+ − ,if_ctl
+ − #endif
+ − );
+ − }
+ − // Increment tpu window identifier.
+ − l1s.tpu_win += (l1_config.params.rx_synth_load_split + PWR_LOAD);
+ − }
+ −
+ − // Flag DSP and TPU programmation.
+ − // ********************************
+ −
+ − // Set "CTRL_MS" flag in the controle flag register.
+ − l1s.tpu_ctrl_reg |= CTRL_MS;
+ − l1s.dsp_ctrl_reg |= CTRL_MS;
+ −
+ − // This task is not compatible with Neigh. Measurement. Store task length
+ − // in "forbid_meas" to indicate when the task will last.
+ − l1s.forbid_meas = TASK_ROM_MFTAB[task].size;
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_fb() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* tasks: FBNEW,FB51. This function is the control */
+ − /* function for making a frequency burst acquisition on */
+ − /* a neighbor cell. It programs the DSP and the TPU for */
+ − /* making 1 attempt in reading the frequency burst.Here */
+ − /* is a summary of the execution: */
+ − /* */
+ − /* - If SEMAPHORE(task) is low. */
+ − /* - Traces and debug. */
+ − /* - Programs DSP for FB acquisition task. */
+ − /* - Programs TPU for FB acquisition task. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* FBNEW, Frequency Burst detection task in Idle mode. */
+ − /* FB51, Frequency Burst detection task in Dedicated */
+ − /* mode. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.task_param" */
+ − /* task semaphore bit register. Used to skip this */
+ − /* control if L1A has changed or is changing some of */
+ − /* the task parameters. */
+ − /* */
+ − /* "l1a_l1s_com.Ncell_info.acquis" */
+ − /* cell information structure used for FBNEW and FB51 */
+ − /* tasks. */
+ − /* */
+ − /* "l1a_l1s_com.fb_mode" */
+ − /* the frequency burst detection algorithm implemented */
+ − /* in the DSP uses 2 different modes. The mode to use */
+ − /* is indicated by this global variable and is passed */
+ − /* to the DSP. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.tpu_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/TPU */
+ − /* interface. This is used mainly to swap then the */
+ − /* com. page at the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /* "l1s.dsp_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/DSP */
+ − /* interface. This is used mainly to swap then the */
+ − /* com. page at the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_ctrl_fb(UWORD8 task, UWORD8 param2)
+ − {
+ − WORD8 agc;
+ − UWORD8 lna_off;
+ − BOOL en_task;
+ − BOOL task_param;
+ − UWORD32 dsp_task;
+ − #if (L1_FF_MULTIBAND == 1)
+ − UWORD16 operative_radio_freq;
+ − #endif
+ −
+ −
+ − // Get "enable" task flag and "synchro semaphore" for current task.
+ − en_task = l1a_l1s_com.l1s_en_task[task];
+ − task_param = l1a_l1s_com.task_param[task];
+ −
+ − if((en_task) && !(task_param))
+ − // Check the task semaphore and enable flag. The control body is executed only
+ − // when the task semaphore is 0 and enable flag is 1. The semaphore can be set to
+ − // 1 whenever L1A makes some changes to the task parameters. The enable can be
+ − // reset to 0 when the task is no more enabled.
+ − {
+ − T_NCELL_SINGLE *cell_info_ptr = NULL;
+ −
+ − // Get the cell information structure.
+ − // ************************************
+ − cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id];
+ −
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_FB, cell_info_ptr->radio_freq);
+ − #endif
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+ − #endif
+ −
+ − l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 13) ;
+ −
+ − // Programs DSP for required task.
+ − // ********************************
+ −
+ − // dsp pgm...
+ −
+ − dsp_task = l1s_swap_iq_dl(cell_info_ptr->radio_freq,task);
+ −
+ − l1ddsp_load_monit_task(dsp_task, l1a_l1s_com.fb_mode);
+ −
+ − // Programs TPU for required task.
+ − // ********************************
+ − #if (L1_FF_MULTIBAND == 0)
+ −
+ − // Get AGC to be applied.
+ − agc = Cust_get_agc_from_IL(cell_info_ptr->radio_freq,l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].input_level >> 1, AV_ID);
+ − // lna_off flag is updated ONLY in case of l1ctl_pgc2 control algo
+ − lna_off = l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+ −
+ − #else // L1_FF_MULTIBAND = 1 below
+ −
+ − operative_radio_freq = l1_multiband_radio_freq_convert_into_operative_radio_freq(cell_info_ptr->radio_freq );
+ − // lna_off flag is updated ONLY in case of l1ctl_pgc2 control algo
+ − lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+ − // Get AGC to be applied.
+ − agc = Cust_get_agc_from_IL(cell_info_ptr->radio_freq,l1a_l1s_com.last_input_level[operative_radio_freq].input_level >> 1, AV_ID);
+ −
+ − #endif // #if (L1_FF_MULTIBAND == 0) else
+ −
+ −
+ − // tpu pgm...
+ − l1dtpu_neig_fb(cell_info_ptr->radio_freq, agc, lna_off);
+ − }
+ −
+ − // Flag DSP and TPU programmation.
+ − // ********************************
+ −
+ − // Set "CTRL_RX" flag in the controle flag register.
+ − l1s.tpu_ctrl_reg |= CTRL_RX;
+ − l1s.dsp_ctrl_reg |= CTRL_RX;
+ −
+ − // This task is not compatible with Neigh. Measurement. Store task length
+ − // in "forbid_meas" to indicate when the task will last.
+ − // Rem: Only FB51 task starts from this ctrl function.
+ − if(task==FB51) l1s.forbid_meas = TASK_ROM_MFTAB[task].size;
+ − }
+ −
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_fbsb() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* tasks: FBSB. This function is the control */
+ − /* function for making a frequency + synchro burst */
+ − /* on a neighbor cell in case of blind handover */
+ − /* It programs the DSP and the TPU for */
+ − /* making 1 attempt in reading the frequency & synchro */
+ − /* burst */
+ − /* Here is a summary of the execution: */
+ − /* */
+ − /* - If SEMAPHORE(task) is low. */
+ − /* - Traces and debug. */
+ − /* - Programs DSP for FB+SB acquisition task. */
+ − /* - Programs TPU for FB+SB acquisition task. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* FBSB, Frequency + Synchro burst detection task in */
+ − /* blind handover */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.task_param" */
+ − /* task semaphore bit register. Used to skip this */
+ − /* control if L1A has changed or is changing some of */
+ − /* the task parameters. */
+ − /* */
+ − /* "l1a_l1s_com.nsync_fbsb" */
+ − /* cell information structure used for FBSB tasks. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.tpu_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/TPU */
+ − /* interface. This is used mainly to swap then the */
+ − /* com. page at the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /* "l1s.dsp_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/DSP */
+ − /* interface. This is used mainly to swap then the */
+ − /* com. page at the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − #if ((REL99 == 1) && (FF_BHO == 1))
+ − void l1s_ctrl_fbsb(UWORD8 task, UWORD8 param2)
+ − {
+ −
+ − WORD8 agc;
+ − UWORD8 lna_off;
+ − UWORD32 dsp_task;
+ − //added by sajal for DCXO
+ − UWORD8 input_level;
+ − #if (RF_FAM == 61)
+ − UWORD16 dco_algo_ctl_sb = 0;
+ − UWORD8 if_ctl = 0;
+ − UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+ − #endif
+ − #if (L1_FF_MULTIBAND == 1)
+ − UWORD16 operative_radio_freq;
+ − #endif
+ −
+ −
+ −
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE!=0)
+ − // trace_fct(CST_L1S_CTRL_FBSB, l1a_l1s_com.nsync_fbsb.radio_freq);
+ − #endif
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+ − #endif
+ −
+ − l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 13) ;
+ −
+ − // Programs DSP for required task.
+ − // ********************************
+ −
+ − // dsp pgm...
+ −
+ − dsp_task = l1s_swap_iq_dl(l1a_l1s_com.nsync_fbsb.radio_freq, task);
+ −
+ − l1ddsp_load_monit_task(dsp_task, 1);
+ − #if (L1_FF_MULTIBAND == 0)
+ − input_level = l1a_l1s_com.last_input_level[l1a_l1s_com.nsync_fbsb.radio_freq - l1_config.std.radio_freq_index_offset].input_level;
+ − #else
+ − operative_radio_freq =
+ − l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.nsync_fbsb.radio_freq);
+ − input_level =
+ − l1a_l1s_com.last_input_level[operative_radio_freq].input_level;
+ − #endif
+ −
+ − #if (RF_FAM == 61) // Locosto DCO
+ − cust_get_if_dco_ctl_algo(&dco_algo_ctl_sb, &if_ctl, (UWORD8) L1_IL_VALID ,
+ − input_level,
+ − l1a_l1s_com.nsync_fbsb.radio_freq,if_threshold);
+ −
+ − l1ddsp_load_dco_ctl_algo_sb(dco_algo_ctl_sb);
+ − #endif
+ −
+ − // Programs TPU for required task.
+ − // ********************************
+ − #if (L1_FF_MULTIBAND == 0)
+ −
+ − // lna_off flag is updated ONLY in case of l1ctl_pgc2 control algo
+ − lna_off = l1a_l1s_com.last_input_level[l1a_l1s_com.nsync_fbsb.radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+ −
+ − // Get AGC to be applied.
+ − agc = Cust_get_agc_from_IL(l1a_l1s_com.nsync_fbsb.radio_freq, l1a_l1s_com.last_input_level[l1a_l1s_com.nsync_fbsb.radio_freq - l1_config.std.radio_freq_index_offset].input_level >> 1, AV_ID);
+ −
+ − #else // L1_FF_MULTIBAND = 1 below
+ −
+ − /*operative_radio_freq =
+ − l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.nsync_fbsb.radio_freq);*/
+ −
+ − // lna_off flag is updated ONLY in case of l1ctl_pgc2 control algo
+ − lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+ −
+ − // Get AGC to be applied.
+ − agc =
+ − Cust_get_agc_from_IL(l1a_l1s_com.nsync_fbsb.radio_freq, l1a_l1s_com.last_input_level[operative_radio_freq].input_level >> 1, AV_ID);
+ −
+ − #endif // #if (L1_FF_MULTIBAND == 0) else
+ −
+ − // tpu pgm...
+ −
+ − l1dtpu_neig_fbsb(l1a_l1s_com.nsync_fbsb.radio_freq, agc, lna_off);
+ −
+ − // Disable Task
+ − // FTH l1a_l1s_com.l1s_en_task[FBSB] = TASK_DISABLED;
+ −
+ − // Flag DSP and TPU programmation.
+ − // ********************************
+ −
+ − // Set "CTRL_RX" flag in the controle flag register.
+ − l1s.tpu_ctrl_reg |= CTRL_RX;
+ − l1s.dsp_ctrl_reg |= CTRL_RX;
+ − }
+ − #endif //#if ((REL99 == 1) && (FF_BHO == 1))
+ −
+ −
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_sbgen() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* tasks: SB1,SB2,SB51,SBCONF,SBCNF51. This function is */
+ − /* the control function for making a synchro burst */
+ − /* reading on a neighbor cell in Cell Selection, Idle */
+ − /* mode and dedicated mode SDCCH. It programs the DSP */
+ − /* and the TPU for making 1 attempt in reading the */
+ − /* synchro burst. Here is a summary of the execution: */
+ − /* */
+ − /* - If SEMAPHORE(task) is low. */
+ − /* - Get the cell information structure. */
+ − /* - Traces and debug. */
+ − /* - Programs DSP for SB reading task. */
+ − /* - Programs TPU for SB reading task. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* SB1, Synchro Burst reading task in Idle mode. */
+ − /* SB2, Synchro Burst detection task in Idle mode. */
+ − /* SBCONF, Synchro Burst confirmation task in Idle */
+ − /* mode. */
+ − /* SB51, Synchro Burst reading task in Dedicated mode. */
+ − /* SBCNF51, Synchro Burst confirmation task in */
+ − /* Dedicated mode. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.task_param" */
+ − /* task semaphore bit register. Used to skip this */
+ − /* control if L1A has changed or is changing some of */
+ − /* the task parameters. */
+ − /* */
+ − /* "l1a_l1s_com.Ncell_info.acquis" */
+ − /* cell information structure used for SB1, SB2 and */
+ − /* SB51 tasks. */
+ − /* */
+ − /* "l1a_l1s_com.Ncell_info.conf" */
+ − /* cell information structure used for SBCONF and */
+ − /* SBCNF51 tasks. */
+ − /* */
+ − /* "l1s.tpu_offset" */
+ − /* value for SYNCHRO and OFFSET register in the TPU */
+ − /* for current serving cell setting. It is used here */
+ − /* by the synchro burst reading TPU driver since this */
+ − /* driver changes the OFFSET register. At the end of */
+ − /* the task it restores the serving cell offset value. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.tpu_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/TPU com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /* "l1s.dsp_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/DSP com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_ctrl_sbgen(UWORD8 task, UWORD8 attempt)
+ − {
+ − UWORD8 reload_serv_offset = TRUE; // Default: offset serving reloaded.
+ − WORD8 agc;
+ − UWORD8 lna_off;
+ − BOOL en_task;
+ − BOOL task_param;
+ − UWORD32 dsp_task;
+ − UWORD8 input_level;
+ − #if (RF_FAM == 61)
+ − UWORD16 dco_algo_ctl_sb = 0;
+ − UWORD8 if_ctl = 0;
+ − UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+ − #endif
+ − #if (L1_FF_MULTIBAND == 1)
+ − UWORD16 operative_radio_freq;
+ − #endif
+ −
+ −
+ − // Get "enable" task flag and "synchro semaphore" for current task.
+ − en_task = l1a_l1s_com.l1s_en_task[task];
+ − task_param = l1a_l1s_com.task_param[task];
+ −
+ − if((en_task) && !(task_param))
+ − // Check the task semaphore and enable flag. The control body is executed only
+ − // when the task semaphore is 0 and enable flag is 1. The semaphore can be set to
+ − // 1 whenever L1A makes some changes to the task parameters. The enable can be
+ − // reset to 0 when the task is no more enabled.
+ − {
+ − T_NCELL_SINGLE *cell_info_ptr = NULL;
+ −
+ − switch(task)
+ − {
+ − case SB2:
+ − {
+ − // Get the cell information structure.
+ − // ************************************
+ − cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sb_id];
+ −
+ − if(attempt == 1) reload_serv_offset = FALSE; // Offset serving not reloaded on 1st CTRL.
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_SB2, cell_info_ptr->radio_freq);
+ − #endif
+ − }
+ − break;
+ −
+ − case SB51:
+ − {
+ − // Get the cell information structure.
+ − // ************************************
+ − cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sb_id];
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_SB51, cell_info_ptr->radio_freq);
+ − #endif
+ − }
+ − break;
+ −
+ − case SBCONF:
+ − case SBCNF51:
+ − {
+ − // Get the cell information structure.
+ − // ************************************
+ − cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sbconf_id];
+ −
+ − #if (TRACE_TYPE!=0)
+ − if(task == SBCONF)
+ − trace_fct(CST_L1S_CTRL_SBCONF, cell_info_ptr->radio_freq);
+ − else
+ − trace_fct(CST_L1S_CTRL_SBCNF51, cell_info_ptr->radio_freq);
+ − #endif
+ − #if (L1_EOTD==1)
+ − // We need to trigger the TOA tracking / adjustment period
+ − // which logs all TOA updates after E-OTD has started...
+ −
+ − if(l1a_l1s_com.nsync.eotd_meas_session == TRUE)
+ − {
+ − if( (l1a_l1s_com.nsync.eotd_toa_phase == 0)
+ − && (l1a_l1s_com.nsync.active_sbconf_id == 12) )
+ − {
+ − l1a_l1s_com.nsync.eotd_toa_tracking = 0;
+ − l1a_l1s_com.nsync.eotd_toa_phase = 1;
+ − }
+ −
+ − l1a_l1s_com.nsync.eotd_cache_toa_tracking = l1a_l1s_com.nsync.eotd_toa_tracking;
+ − }
+ − #endif
+ −
+ −
+ − }
+ − break;
+ −
+ − default: return;
+ − }
+ −
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+ − #endif
+ −
+ − l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 3) ;
+ −
+ − // Programs DSP for required task.
+ − // ********************************
+ −
+ − // dsp pgm...
+ − dsp_task = l1s_swap_iq_dl(cell_info_ptr->radio_freq,task);
+ − l1ddsp_load_monit_task(dsp_task, 0);
+ −
+ − #if (L1_FF_MULTIBAND == 0)
+ − input_level = l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].input_level;
+ − #else // L1_FF_MULTIBAND = 1 below
+ − operative_radio_freq =
+ − l1_multiband_radio_freq_convert_into_operative_radio_freq(cell_info_ptr->radio_freq);
+ − input_level = l1a_l1s_com.last_input_level[operative_radio_freq].input_level;
+ − #endif //#if (L1_FF_MULTIBAND == 0) else
+ −
+ − #if (RF_FAM == 61) // Locosto DCO
+ − cust_get_if_dco_ctl_algo(&dco_algo_ctl_sb, &if_ctl, (UWORD8) L1_IL_VALID ,
+ − input_level,
+ − cell_info_ptr->radio_freq,if_threshold);
+ −
+ − // This is a work-around for a DSP problem (OMAPS00117845)
+ − // The problem happens during neighbor FB/SB, when there is an
+ − // IDLE frame between neighbor FB and SB.
+ − // Neighbor cell SB(SB2) is different from other kind of SB decode.
+ − // For SB2 we open the RF window for 2 frames (2 C W W R)
+ − // For both Control, l1s_dsp_com.dsp_db_common_w_ptr->d_dco_algo_ctrl_sb is updated.
+ − // However DSP copies DB value to NDB and this value is copied only once.
+ − // At the end of the first SB, DSP right shifts the NDB variable.
+ − // The fix below replicates the DCO control information 4 times
+ − // so that DSP has correct information even after right shifting during first SB.
+ −
+ − if(task == SB2)
+ − {
+ − dco_algo_ctl_sb *= 0x55;
+ − }
+ −
+ −
+ −
+ −
+ − l1ddsp_load_dco_ctl_algo_sb(dco_algo_ctl_sb);
+ − #endif
+ −
+ − // Programs TPU for required task.
+ − // ********************************
+ − #if (L1_FF_MULTIBAND == 0)
+ −
+ − // Get AGC to be applied.
+ − agc = Cust_get_agc_from_IL(cell_info_ptr->radio_freq, input_level >> 1, AV_ID);
+ − // lna_off flag is ONLY updated in case of l1ctl_pgc2 control algorithm
+ − lna_off = l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+ −
+ − #else // L1_FF_MULTIBAND = 0 below
+ −
+ − operative_radio_freq =
+ − l1_multiband_radio_freq_convert_into_operative_radio_freq(cell_info_ptr->radio_freq);
+ − // lna_off flag is ONLY updated in case of l1ctl_pgc2 control algorithm
+ − lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+ − // Get AGC to be applied.
+ − agc =
+ − Cust_get_agc_from_IL(cell_info_ptr->radio_freq, input_level >> 1, AV_ID);
+ −
+ − #endif // #if (L1_FF_MULTIBAND == 0) else
+ −
+ − // tpu pgm...
+ − l1dtpu_neig_sb(cell_info_ptr->radio_freq,
+ − agc,
+ − lna_off,
+ − cell_info_ptr->time_alignmt,
+ − l1s.tpu_offset,
+ − reload_serv_offset,
+ − attempt
+ − #if (RF_FAM == 61)
+ − ,if_ctl
+ − #endif
+ − );
+ −
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET_NEIGH)
+ − buffer_trace(4, l1s.actual_time.fn, cell_info_ptr->radio_freq,
+ − cell_info_ptr->time_alignmt,l1s.tpu_offset);
+ − #endif
+ − #endif
+ − }
+ − else
+ − // The task has been disabled or some parameters have changed, the serving tpu offset
+ − // must be restored.
+ − {
+ − if(attempt==2)
+ − {
+ − l1dmacro_offset(l1s.tpu_offset,IMM);
+ − }
+ − }
+ −
+ − // Flag DSP and TPU programmation.
+ − // ********************************
+ −
+ − // Set "CTRL_RX" flag in the controle flag register.
+ − l1s.tpu_ctrl_reg |= CTRL_RX;
+ − l1s.dsp_ctrl_reg |= CTRL_RX;
+ −
+ − // This task is not compatible with Neigh. Measurement. Store task length
+ − // in "forbid_meas" to indicate when the task will last.
+ − // Rem: Only SB51/SBCNF51 tasks start from this ctrl function.
+ − if((task==SB51)||(task==SBCNF51)) l1s.forbid_meas = TASK_ROM_MFTAB[task].size;
+ − }
+ −
+ − #if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_fb26() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* tasks: FB26. This function is the control function */
+ − /* for making a frequency burst acquisition attempt on */
+ − /* a neighbor cell in dedicated mode TCH. It programs */
+ − /* the DSP and the TPU for making 1 attempt in reading */
+ − /* the frequency burst.Here is a summary of the */
+ − /* execution: */
+ − /* */
+ − /* - If SEMAPHORE(task) is low. */
+ − /* - Traces and debug. */
+ − /* - Programs DSP for FB acquisition task. */
+ − /* - Programs TPU for FB acquisition task. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.Ncell_info.acquis" */
+ − /* cell information structure used for FB26 task. */
+ − /* */
+ − /* "l1s.tpu_offset" */
+ − /* value for SYNCHRO and OFFSET register in the TPU */
+ − /* for current serving cell setting. It is used here */
+ − /* by the frequency burst reading TPU driver since */
+ − /* this driver changes the OFFSET register. At the end */
+ − /* of the task it restores the serving cell offset */
+ − /* value. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.tpu_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/TPU com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /* "l1s.dsp_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/DSP com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_ctrl_fb26(UWORD8 param1, UWORD8 param2)
+ − {
+ − WORD8 agc;
+ − BOOL lna_off;
+ − UWORD32 dsp_task;
+ − UWORD16 radio_freq = 0;
+ − #if (L1_FF_MULTIBAND == 1)
+ − UWORD16 operative_radio_freq;
+ − #endif
+ −
+ − #if (L1_12NEIGH ==1)
+ − BOOL en_task;
+ − BOOL task_param;
+ −
+ − // Get "enable" task flag and "synchro semaphore" for current task.
+ − en_task = l1a_l1s_com.l1s_en_task[param1];
+ − task_param = l1a_l1s_com.task_param[param1];
+ −
+ − if((en_task) && !(task_param))
+ − // Check the task semaphore and enable flag. The control body is executed only
+ − // when the task semaphore is 0 and enable flag is 1. The semaphore can be set to
+ − // 1 whenever L1A makes some changes to the task parameters. The enable can be
+ − // reset to 0 when the task is no more enabled.
+ − #else
+ − if(!(l1a_l1s_com.task_param[FB26] == SEMAPHORE_SET))
+ − #endif
+ − // Check the task semaphore. The control body is executed only
+ − // when the task semaphore is 0. This semaphore can be set to
+ − // 1 whenever L1A makes some changes to the task parameters.
+ − {
+ − #if (L1_12NEIGH ==1)
+ − T_NCELL_SINGLE *cell_info_ptr = NULL;
+ −
+ − cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id];
+ − radio_freq = cell_info_ptr->radio_freq;
+ − #else
+ − radio_freq = l1a_l1s_com.nsync.list[0].radio_freq;
+ − #endif
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_FB26, radio_freq);
+ − #endif
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsp_tpu(dltsk_trace[FB26].name);
+ − #endif
+ −
+ − // Programs DSP for FB26 task.
+ − // ****************************
+ −
+ − // dsp pgm...
+ −
+ − dsp_task = l1s_swap_iq_dl(radio_freq,FB26);
+ −
+ − l1ddsp_load_monit_task(dsp_task, 1);
+ −
+ − // Programs TPU for FB26 task.
+ − // ****************************
+ − #if (L1_FF_MULTIBAND == 0)
+ −
+ − // agc is just computed from last stored IL
+ − agc = Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.last_input_level[radio_freq - l1_config.std.radio_freq_index_offset].input_level >> 1, AV_ID);
+ − lna_off = l1a_l1s_com.last_input_level[radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+ −
+ − #else // L1_FF_MULTIBAND = 1 below
+ −
+ − operative_radio_freq =
+ − l1_multiband_radio_freq_convert_into_operative_radio_freq(radio_freq);
+ − lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+ − // agc is just computed from last stored IL
+ − agc =
+ − Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.last_input_level[operative_radio_freq].input_level >> 1, AV_ID);
+ −
+ − #endif // #if (L1_FF_MULTIBAND == 1) else
+ −
+ −
+ − // tpu pgm...
+ − l1dtpu_neig_fb26(radio_freq,
+ − agc,
+ − lna_off,
+ − l1s.tpu_offset);
+ − }
+ −
+ − // Flag DSP and TPU programmation.
+ − // ********************************
+ −
+ − // Set "CTRL_RX" flag in the controle flag register.
+ − l1s.tpu_ctrl_reg |= CTRL_RX;
+ − l1s.dsp_ctrl_reg |= CTRL_RX;
+ −
+ − // This task is not compatible with Neigh. Measurement. Store task length
+ − // in "forbid_meas" to indicate when the task will last.
+ − // Special case: we set forbid_meas to skip the measurements in the frames
+ − // FN%26=24 or 25.
+ − l1s.forbid_meas = 3;
+ − }
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+ − #endif // MOVE_IN_INTERNAL_RAM
+ −
+ − #if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_sb26() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* tasks: SB1,SB2,SB51,SBCONF,SBCNF51. This function is */
+ − /* the control function for making a synchro burst */
+ − /* reading on a neighbor cell in Cell Selection, Idle */
+ − /* mode and dedicated mode SDCCH. It programs the DSP */
+ − /* and the TPU for making 1 attempt in reading the */
+ − /* synchro burst. Here is a summary of the execution: */
+ − /* */
+ − /* - If SEMAPHORE(task) is low. */
+ − /* - Get the cell information structure. */
+ − /* - Traces and debug. */
+ − /* - Programs DSP for SB reading task. */
+ − /* - Programs TPU for SB reading task. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* SB26, Synchro Burst reading task in Dedicated mode, */
+ − /* TCH. */
+ − /* SBCNF26, Synchro Burst confirmation task in Dedic. */
+ − /* mode TCH. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.Ncell_info.acquis" */
+ − /* cell information structure used for SB26 task. */
+ − /* */
+ − /* "l1a_l1s_com.Ncell_info.conf" */
+ − /* cell information structure used for SBCNF26 task. */
+ − /* */
+ − /* "l1s.tpu_offset" */
+ − /* value for SYNCHRO and OFFSET register in the TPU */
+ − /* for current serving cell setting. It is used here */
+ − /* by the synchro burst reading TPU driver since this */
+ − /* driver changes the OFFSET register. At the end of */
+ − /* the task it restores the serving cell offset value. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.tpu_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/TPU com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /* "l1s.dsp_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/DSP com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_ctrl_sb26(UWORD8 task, UWORD8 param2)
+ − {
+ − UWORD32 nb_nop = 0;
+ − WORD8 agc;
+ − BOOL lna_off;
+ − UWORD32 dsp_task;
+ − UWORD8 input_level;
+ − UWORD32 temp;
+ − #if (L1_FF_MULTIBAND == 1)
+ − UWORD16 operative_radio_freq;
+ − #endif
+ −
+ − #if (L1_12NEIGH ==1)
+ − BOOL en_task;
+ − BOOL task_param;
+ − #if (RF_FAM == 61)
+ − UWORD16 dco_algo_ctl_sb = 0;
+ − UWORD8 if_ctl = 0 ;
+ − UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+ − #endif
+ −
+ − // Get "enable" task flag and "synchro semaphore" for current task.
+ − en_task = l1a_l1s_com.l1s_en_task[task];
+ − task_param = l1a_l1s_com.task_param[task];
+ −
+ − if((en_task) && !(task_param))
+ − #else
+ − if(!(l1a_l1s_com.task_param[task]))
+ − #endif
+ − // Check the task semaphore. The control body is executed only
+ − // when the task semaphore is 0. This semaphore can be set to
+ − // 1 whenever L1A makes some changes to the task parameters.
+ − {
+ − UWORD16 radio_freq = 0;
+ − UWORD32 time_alignmt = 0;
+ − #if (L1_12NEIGH ==1)
+ − T_NCELL_SINGLE *cell_info_ptr;
+ −
+ − if (task == SB26)
+ − cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sb_id];
+ − if (task == SBCNF26)
+ − {
+ −
+ − #if (L1_EOTD==1)
+ − // We need to trigger the TOA tracking / adjustment period
+ − // which logs all TOA updates after E-OTD has started...
+ −
+ − if(l1a_l1s_com.nsync.eotd_meas_session == TRUE)
+ − {
+ − if( (l1a_l1s_com.nsync.eotd_toa_phase == 0)
+ − && (l1a_l1s_com.nsync.active_sbconf_id == 12) )
+ − {
+ − l1a_l1s_com.nsync.eotd_toa_tracking = 0;
+ − l1a_l1s_com.nsync.eotd_toa_phase = 1;
+ − }
+ −
+ − l1a_l1s_com.nsync.eotd_cache_toa_tracking = l1a_l1s_com.nsync.eotd_toa_tracking;
+ − }
+ − #endif
+ −
+ − cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sbconf_id];
+ −
+ − }
+ − radio_freq = cell_info_ptr->radio_freq;
+ − time_alignmt = cell_info_ptr->time_alignmt;
+ −
+ − #else
+ − // Get the cell information.
+ − // **************************
+ − radio_freq = l1a_l1s_com.nsync.list[0].radio_freq;
+ − time_alignmt = l1a_l1s_com.nsync.list[0].time_alignmt;
+ − #endif
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE!=0)
+ − switch(task)
+ − {
+ − case SB26: trace_fct(CST_L1S_CTRL_SB26, radio_freq); break;
+ − case SBCNF26: trace_fct(CST_L1S_CTRL_SBCNF26, radio_freq); break;
+ − }
+ − #endif
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+ − #endif
+ −
+ − // Programs DSP for required task.
+ − // ********************************
+ − // dsp pgm...
+ −
+ − dsp_task = l1s_swap_iq_dl(radio_freq,task);
+ − l1ddsp_load_monit_task(dsp_task, 0);
+ −
+ − // Programs TPU for required task.
+ − // ********************************
+ − temp = (UWORD32)(l1_config.params.fb26_anchoring_time - EPSILON_SYNC);
+ − #if (L1_12NEIGH ==1)
+ − if((cell_info_ptr->sb26_offset == 1) &&
+ − (time_alignmt >= temp)) //omaps00090550
+ − #else
+ − if((l1a_l1s_com.nsync.list[0].sb26_offset == 1) &&
+ − (time_alignmt >= temp)) //omaps00090550
+ − #endif
+ − // SB is in the 2nd frame of the search slot...
+ − // ...and SB is at the very end of the slot.
+ − // We insert a nop in the tpu scenario to
+ − // be able to jump the 1st frame.
+ − {
+ − nb_nop = 1;
+ − }
+ −
+ − #if (L1_FF_MULTIBAND == 0)
+ −
+ − // agc is just computed from last stored IL
+ − input_level = l1a_l1s_com.last_input_level[radio_freq - l1_config.std.radio_freq_index_offset].input_level;
+ − agc = Cust_get_agc_from_IL(radio_freq, input_level >> 1, AV_ID);
+ − lna_off = l1a_l1s_com.last_input_level[radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+ −
+ − #else // L1_FF_MULTIBAND = 1 below
+ −
+ − operative_radio_freq =
+ − l1_multiband_radio_freq_convert_into_operative_radio_freq(radio_freq);
+ − // agc is just computed from last stored IL
+ − input_level = l1a_l1s_com.last_input_level[operative_radio_freq].input_level;
+ − lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+ − agc = Cust_get_agc_from_IL(radio_freq, input_level >> 1, AV_ID);
+ −
+ − #endif // #if (L1_FF_MULTIBAND == 0) else
+ −
+ − #if (RF_FAM == 61) // Locosto DCO
+ − cust_get_if_dco_ctl_algo(&dco_algo_ctl_sb, &if_ctl, (UWORD8) L1_IL_VALID,
+ − input_level,
+ − radio_freq,if_threshold);
+ − l1ddsp_load_dco_ctl_algo_sb(dco_algo_ctl_sb);
+ − #endif
+ −
+ − // tpu pgm...
+ − l1dtpu_neig_sb26(radio_freq,
+ − agc,
+ − lna_off,
+ − time_alignmt,
+ − nb_nop,
+ − l1s.tpu_offset
+ − #if (RF_FAM == 61)
+ − ,if_ctl
+ − #endif
+ − );
+ − }
+ −
+ − // Flag DSP and TPU programmation.
+ − // ********************************
+ −
+ − // Set "CTRL_RX" flag in the controle flag register.
+ − l1s.tpu_ctrl_reg |= CTRL_RX;
+ − l1s.dsp_ctrl_reg |= CTRL_RX;
+ −
+ − // This task is not compatible with Neigh. Measurement. Store task length
+ − // in "forbid_meas" to indicate when the task will last.
+ − // Special case: we set forbid_meas to skip the measurements in the frames
+ − // FN%26=24 or 25.
+ − l1s.forbid_meas = 3;
+ − }
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+ − #endif // MOVE_IN_INTERNAL_RAM
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_smscb() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* tasks: SMSCB. This function is the control function */
+ − /* for reading a CBCH burst on the serving cell. It */
+ − /* shifts the OFFSET register to match the normal burst */
+ − /* receive task with the CBCH timeslot number (0,1,2 or */
+ − /* 3), programs a normal burst reading and restores the */
+ − /* OFFSET to the serving cell timeslot 0. On the last */
+ − /* control (4th burst), the SYNCHRO/OFFSET registers are */
+ − /* shifted back to the normal idle mode PCH reading */
+ − /* setting. Here is a summary of the execution: */
+ − /* */
+ − /* - If SEMAPHORE(task) is low. */
+ − /* - Traces and debug. */
+ − /* - Programs DSP for SMSCB task, reading 1 burst. */
+ − /* - Programs TPU for SMSCB task, reading 1 burst. */
+ − /* - Shift TPU SYNCHRO/OFFSET registers back to the */
+ − /* PAGING TASK timeslot. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* SMSCB, Short Message Service Cell Broadcast. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.cbch_desc" */
+ − /* Cell Broadcast CHannel description structure. */
+ − /* */
+ − /* "l1a_l1s_com.Scell_info.bsic" */
+ − /* BSIC of the serving cell. It is used here to pass */
+ − /* the training sequence number (part of BSIC) to the */
+ − /* DSP. */
+ − /* */
+ − /* "l1s.afc" */
+ − /* current AFC value to be applied for SMSCB reading */
+ − /* task. */
+ − /* */
+ − /* "l1a_l1s_com.offset_tn0" */
+ − /* value to load in the OFFSET register to shift then */
+ − /* any receive task to the timeslot 0 of the serving */
+ − /* cell. This is the default setting to restore after */
+ − /* any CBCH burst reading. */
+ − /* */
+ − /* "l1s.tpu_offset" */
+ − /* value for the TPU SYNCHRO and OFFSET registers */
+ − /* for current serving cell setting. It is used here */
+ − /* at the end of the CBCH task controls to restore the */
+ − /* SYNCHRO/OFFSET registers to the normal setting in */
+ − /* idle mode. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.actual_time, l1s.next_time" */
+ − /* frame number and derived numbers for current frame */
+ − /* and next frame. */
+ − /* -> update to cope with side effect due to synchro. */
+ − /* changes/restores. */
+ − /* */
+ − /* "l1s.tpu_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/TPU com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /* "l1s.dsp_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/DSP com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_ctrl_smscb(UWORD8 task, UWORD8 burst_id)
+ − {
+ − UWORD16 rx_radio_freq;
+ − UWORD32 offset_smscb;
+ − WORD8 agc;
+ − UWORD8 lna_off;
+ − UWORD32 dsp_task;
+ − static WORD32 new_tpu_offset;
+ − static BOOL change_synchro;
+ − #if 0 /* FreeCalypso TCS211 reconstruction */
+ − UWORD8 input_level;
+ − #endif
+ − #if (L1_FF_MULTIBAND == 1)
+ − UWORD16 operative_radio_freq;
+ − #endif
+ −
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − UWORD8 saic_flag=0;
+ − #endif /* NEW_SNR_THRESHOLD */
+ − #if (RF_FAM == 61)
+ − UWORD16 dco_algo_ctl_nb = 0;
+ − UWORD8 if_ctl = 0;
+ − UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+ − // By default we choose the hardware filter
+ − UWORD8 csf_filter_choice = L1_SAIC_HARDWARE_FILTER;
+ − #endif
+ −
+ − // Needed for simulated DSP GRPS scheduler
+ − #if (CODE_VERSION == SIMULATION)
+ − UWORD32 tpu_w_page;
+ −
+ − if (hw.tpu_r_page==0)
+ − tpu_w_page=1;
+ − else
+ − tpu_w_page=0;
+ −
+ − hw.rx_id[tpu_w_page][0]=0;
+ − hw.num_rx[tpu_w_page][0]=1;
+ − hw.rx_group_id[tpu_w_page]=1;
+ − #endif
+ −
+ −
+ − if((l1a_l1s_com.l1s_en_task[task] == TASK_ENABLED) &&
+ − !(l1a_l1s_com.task_param[task] == SEMAPHORE_SET))
+ − // Check the task semaphore. The control body is executed only
+ − // when the task semaphore is 0. This semaphore can be set to
+ − // 1 whenever L1A makes some changes to the task parameters.
+ − {
+ − // Get ARFCN to be used for current control. Output of the hopping algorithm.
+ − rx_radio_freq = l1a_l1s_com.dedic_set.radio_freq;
+ −
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+ − #endif
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_SMSCB, rx_radio_freq);
+ − #endif
+ −
+ − l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+ −
+ − // Programs DSP for SMSCB task according to the DSP scheduler used
+ − // ****************************************************************
+ −
+ − #if L1_GPRS
+ − switch(l1a_l1s_com.dsp_scheduler_mode)
+ − {
+ − // dsp pgm is made using GSM scheduler...
+ − case GSM_SCHEDULER:
+ − {
+ − dsp_task = l1s_swap_iq_dl(rx_radio_freq, task);
+ −
+ − // dsp pgm...
+ − l1ddsp_load_rx_task(dsp_task,burst_id,l1a_l1s_com.cbch_desc.tsc);
+ − }
+ − break;
+ −
+ − // dsp pgm is made using GPRS scheduler...
+ − case GPRS_SCHEDULER:
+ − {
+ − #if FF_L1_IT_DSP_USF
+ − l1pddsp_idle_rx_nb(burst_id,l1a_l1s_com.cbch_desc.tsc,rx_radio_freq,0,FALSE,FALSE);
+ − #else
+ − l1pddsp_idle_rx_nb(burst_id,l1a_l1s_com.cbch_desc.tsc,rx_radio_freq,0,FALSE);
+ − #endif
+ − }
+ − break;
+ − }
+ − #else
+ − dsp_task = l1s_swap_iq_dl(rx_radio_freq, task);
+ −
+ − // dsp pgm...
+ − l1ddsp_load_rx_task(dsp_task,burst_id,l1a_l1s_com.cbch_desc.tsc);
+ − #endif
+ −
+ − // Check if "Synchro" change is needed.
+ − // *************************************
+ −
+ − // If so the synchro is changed by 4 timeslots.
+ − if(burst_id == BURST_1)
+ − {
+ − // This task is not compatible with Neigh. Measurement. Store task length
+ − // in "forbid_meas" to indicate when the task will last.
+ − l1s.forbid_meas = TASK_ROM_MFTAB[task].size;
+ −
+ − change_synchro = l1a_l1s_com.change_synchro_cbch;
+ −
+ − if(change_synchro)
+ − {
+ − // compute TPU offset for "current timeslot + 4 timeslot"
+ − new_tpu_offset = l1s.tpu_offset + (4 * TN_WIDTH);
+ −
+ − if(new_tpu_offset >= TPU_CLOCK_RANGE)
+ − new_tpu_offset -= TPU_CLOCK_RANGE;
+ −
+ − // Slide synchro to match current timeslot + 4 timeslot.
+ − l1dmacro_synchro(l1_config.params.rx_change_synchro_time, new_tpu_offset);
+ − }
+ − else
+ − {
+ − new_tpu_offset = l1s.tpu_offset;
+ − }
+ − }
+ −
+ − // Programs TPU for SMSCB task, reading 1 burst.
+ − // **********************************************
+ −
+ − offset_smscb = new_tpu_offset + l1a_l1s_com.tn_smscb * TN_WIDTH;
+ − if (offset_smscb >= TPU_CLOCK_RANGE)
+ − offset_smscb -= TPU_CLOCK_RANGE;
+ −
+ − #if 1 /* FreeCalypso match TCS211 */
+ −
+ − // agc is set with the input_level computed from PAGC algo
+ − agc = Cust_get_agc_from_IL(l1a_l1s_com.Scell_info.radio_freq, l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset].input_level >> 1, MAX_ID);
+ − lna_off = l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+ −
+ − #elif (L1_FF_MULTIBAND == 0)
+ −
+ − // agc is set with the input_level computed from PAGC algo
+ − input_level = l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset].input_level;
+ − agc = Cust_get_agc_from_IL(l1a_l1s_com.Scell_info.radio_freq,input_level >> 1, MAX_ID);
+ − lna_off = l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+ −
+ − #else // L1_FF_MULTIBAND = 1 below
+ −
+ − operative_radio_freq =
+ − l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.Scell_info.radio_freq);
+ − input_level = l1a_l1s_com.last_input_level[operative_radio_freq].input_level;
+ − lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+ − agc = Cust_get_agc_from_IL(l1a_l1s_com.Scell_info.radio_freq,input_level >> 1, MAX_ID);
+ −
+ −
+ − #endif // #if (L1_FF_MULTIBAND == 0) else
+ −
+ − #if(RF_FAM == 61) // Locosto DCO
+ − cust_get_if_dco_ctl_algo(&dco_algo_ctl_nb, &if_ctl, (UWORD8) L1_IL_VALID,
+ − input_level,
+ − l1a_l1s_com.Scell_info.radio_freq,if_threshold);
+ −
+ − l1ddsp_load_dco_ctl_algo_nb(dco_algo_ctl_nb);
+ − #endif
+ −
+ − // Store IL used for current CTRL in order to be able to buil IL from pm
+ − // in READ phase.
+ − #if 1 /* FreeCalypso match TCS211 */
+ −
+ − l1a_l1s_com.Scell_used_IL.input_level = l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset].input_level;
+ − l1a_l1s_com.Scell_used_IL.lna_off = l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+ −
+ − #elif (L1_FF_MULTIBAND == 0)
+ −
+ − l1a_l1s_com.Scell_used_IL.input_level = input_level;
+ − l1a_l1s_com.Scell_used_IL.lna_off = l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+ −
+ − #else // L1_FF_MULTIBAND = 1 below
+ −
+ − operative_radio_freq =
+ − l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.Scell_info.radio_freq);
+ − l1a_l1s_com.Scell_used_IL.input_level = input_level;
+ − l1a_l1s_com.Scell_used_IL.lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+ −
+ − #endif // #if (L1_FF_MULTIBAND == 1) else
+ −
+ − #if (L1_SAIC != 0)
+ − // If SAIC is enabled, call the low level SAIC control function
+ − csf_filter_choice = l1ctl_saic(l1a_l1s_com.Scell_used_IL.input_level,l1a_l1s_com.mode
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,task
+ − ,&saic_flag
+ − #endif
+ − );
+ − #endif
+ −
+ − // tpu pgm...
+ − l1dtpu_serv_rx_nb(rx_radio_freq,
+ − agc,
+ − lna_off,
+ − new_tpu_offset,
+ − offset_smscb,
+ − TRUE,
+ − FALSE
+ − #if (RF_FAM == 61)
+ − ,csf_filter_choice
+ − ,if_ctl
+ − #endif
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,saic_flag
+ − #endif /* NEW_SNR_THRESHOLD */
+ − );
+ −
+ − } // End if(task enabled and semaphore false)
+ −
+ − // Remark:
+ − //--------
+ − // When the task is aborted, we must continue to make dummy
+ − // DSP programming to avoid communication mismatch due
+ − // to C/W/R pipelining.
+ −
+ − // We must also ensure the Synchro back since synchro change has surely be done
+ − // in the 1st CTRL phase.
+ −
+ − // Shift TPU SYNCHRO/OFFSET registers back to the default timeslot (normally (P)CCCH one).
+ − // ****************************************************************************************
+ − // When the CBCH reading control is completed (4 burst controled),
+ − // the SYNCHRO/OFFSET registers are shifted back to the normal idle
+ − // setting used for (P)CCCH reading on the serving cell.
+ −
+ − // Check if "Synchro" change was needed.
+ − // If so the synchro is changed to recover normal synchro.
+ − if(burst_id == BURST_4)
+ − {
+ − if(change_synchro)
+ − {
+ − // Slide synchro back to mach current serving timeslot.
+ − l1dmacro_synchro(SWITCH_TIME, l1s.tpu_offset);
+ −
+ − // Increment frame number.
+ − #if L1_GPRS
+ − l1s.actual_time = l1s.next_time;
+ − l1s.next_time = l1s.next_plus_time;
+ − l1s_increment_time(&(l1s.next_plus_time), 1); // Increment "next_plus time".
+ − #else
+ − l1s.actual_time = l1s.next_time;
+ − l1s_increment_time(&(l1s.next_time), 1); // Increment "next time".
+ − #endif
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − trace_fct(CST_L1S_ADJUST_TIME, (UWORD32)(-1));//OMAPS00090550
+ − #endif
+ −
+ − l1s.tpu_ctrl_reg |= CTRL_SYCB;
+ − l1s.dsp_ctrl_reg |= CTRL_SYNC;
+ − }
+ − }
+ −
+ − // Flag DSP and TPU programmation.
+ − // ********************************
+ −
+ − // Set "CTRL_RX" flag in the controle flag register.
+ − l1s.tpu_ctrl_reg |= CTRL_RX;
+ − l1s.dsp_ctrl_reg |= CTRL_RX;
+ − }
+ −
+ − #if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM !=0)) // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM enabled
+ − //#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_START // KEEP IN EXTERNAL MEM otherwise
+ −
+ − #if 0 /* FreeCalypso TCS211 reconstruction */
+ − UWORD32 qual_acc_idle1[2];
+ − #endif
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_snb_dl() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* serving cell normal burst reading tasks: NP, EP, */
+ − /* BCCHS, ALLC, DDL and ADL. This function is the control*/
+ − /* function for reading a normal burst on the serving */
+ − /* cell. It programs the DSP and the TPU for reading a */
+ − /* normal burst without change on the TPU OFFSET */
+ − /* register and flags the reading of the normal paging */
+ − /* burst. This flag is used by the measurement manager */
+ − /* "l1s_meas_manager()" at the end of L1S. Here is a */
+ − /* summary of the execution: */
+ − /* */
+ − /* - If SEMAPHORE(task) is low. */
+ − /* - Catch ARFCN and set CIPHERING reduced frame */
+ − /* number. */
+ − /* - Traces and debug. */
+ − /* - Programs DSP for required task. */
+ − /* - Programs TPU for required task. */
+ − /* - Flag the reading of a Normal Paging burst. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* NP, Normal paging reading task. */
+ − /* EP, Extended paging reading task. */
+ − /* BCCHS, BCCH Serving reading task. */
+ − /* ALLC, All serving cell CCCH reading task. */
+ − /* */
+ − /* DDL, SDCCH DOWNLINK reading task. */
+ − /* ADL, SACCH DOWNLINK (associated with SDCCH)reading */
+ − /* task. */
+ − /* */
+ − /* "burst_id" */
+ − /* BURST_1, 1st burst of the task. */
+ − /* BURST_2, 2nd burst of the task. */
+ − /* BURST_3, 3rd burst of the task. */
+ − /* BURST_4, 4th burst of the task. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.dedic_set" */
+ − /* Dedicated channel parameter structure. It is used */
+ − /* to get the ARFCN to use for SDCCH (DDL, ADL). This */
+ − /* ARFCN comes from the HOPPING algorithm called just */
+ − /* before calling this function. */
+ − /* */
+ − /* "l1a_l1s_com.Scell_info" */
+ − /* Serving cell information structure. */
+ − /* .radio_freq, serving cell beacon frequency. */
+ − /* .bsic, BSIC of the serving cell. It is used here */
+ − /* to pass the training sequence number (part */
+ − /* of BSIC) to the DSP. */
+ − /* */
+ − /* "l1s.afc" */
+ − /* current AFC value to be applied for the given task. */
+ − /* */
+ − /* "l1s.tpu_offset" */
+ − /* value for the TPU SYNCHRO and OFFSET registers */
+ − /* for current serving cell setting. It is used here */
+ − /* to refresh the TPU SYNCHRO and OFFSET registers */
+ − /* with a corrected (time tracking of the serving) */
+ − /* value prior to reading a serving cell normal burst. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.np_ctrl" */
+ − /* Flag set when a normal paging burst reading is */
+ − /* controled. This flag is used by the measurement */
+ − /* manager "l1s_meas_manager()", at the end of L1S, to */
+ − /* scheduling the neighbor cell measurements. */
+ − /* -> set to 1. */
+ − /* */
+ − /* "l1s.tpu_win" */
+ − /* each frame is composed with a maximum of 3 */
+ − /* working/TPU windows (typically RX/TX/PW). This is */
+ − /* a counter used to count the number of windows */
+ − /* used. */
+ − /* -> incremented. */
+ − /* */
+ − /* "l1s.tpu_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/TPU com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /* "l1s.dsp_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/DSP com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_ctrl_snb_dl(UWORD8 task, UWORD8 burst_id)
+ − {
+ − UWORD8 lna_off;
+ − WORD8 agc;
+ − UWORD16 rx_radio_freq;
+ − UWORD8 tsc;
+ − T_INPUT_LEVEL *IL_info_ptr;
+ − UWORD32 dsp_task;
+ − static BOOL change_synchro;
+ − UWORD8 adc_active = INACTIVE;
+ − #if (L1_FF_MULTIBAND == 1)
+ − UWORD16 operative_radio_freq;
+ − #endif /*L1_FF_MULTIBAND*/
+ −
+ − #if L1_GPRS
+ − static BOOL algo_change_synchro_active = FALSE;
+ − static BOOL BCCHS_in_transfert = FALSE;
+ − #endif
+ − #if 0 /* FreeCalypso match TCS211 */
+ − UWORD8 input_level = 0; //omaps00090550
+ − #endif
+ − #if (RF_FAM == 61)
+ − UWORD16 dco_algo_ctl_nb = 0;
+ − UWORD8 if_ctl = 0;
+ − UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+ − // By default we choose the hardware filter
+ − UWORD8 csf_filter_choice = L1_SAIC_HARDWARE_FILTER;
+ − #endif
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − UWORD8 saic_flag=0;
+ − #endif /* NEW_SNR_THRESHOLD */
+ −
+ − #if (FF_L1_FAST_DECODING == 1)
+ − BOOL fast_decoding_authorized = FALSE;
+ −
+ − if ( (burst_id == BURST_1) && (l1a_apihisr_com.fast_decoding.status == C_FAST_DECODING_FORBIDDEN) )
+ − {
+ − l1a_apihisr_com.fast_decoding.status = C_FAST_DECODING_NONE;
+ − }
+ −
+ − fast_decoding_authorized = l1s_check_fast_decoding_authorized(task);
+ −
+ − if ( fast_decoding_authorized && l1s_check_deferred_control(task,burst_id) )
+ − {
+ − /* Control is deferred until the upcoming fast decoding IT */
+ − return;
+ − } /* if (fast_decoding_authorized)*/
+ −
+ − /* In all other cases, control must be performed now. */
+ − #endif /* FF_L1_FAST_DECODING == 1 */
+ −
+ − if(!(l1a_l1s_com.task_param[task] == SEMAPHORE_SET))
+ − // Check the task semaphore. The control body is executed only
+ − // when the task semaphore is 0. This semaphore can be set to
+ − // 1 whenever L1A makes some changes to the task parameters.
+ − {
+ − // Catch ARFCN and set CIPHERING reduced frame number.
+ − // Catch Training sequence.
+ − // ****************************************************
+ −
+ − if((task == DDL) || (task == ADL))
+ − // Dedicated mode SDCCH downlink.
+ − {
+ − // Get ARFCN to be used for current control.
+ − rx_radio_freq = l1a_l1s_com.dedic_set.radio_freq;
+ −
+ − if (rx_radio_freq==l1a_l1s_com.Scell_info.radio_freq) // we are working on a beacon freq.
+ − IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas_beacon;
+ − else
+ − IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas;// we are working on a daughter freq
+ −
+ − // Catch training sequence code from the channel description.
+ − tsc = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->tsc;
+ −
+ − // Set CIPHERING reduced frame number.
+ − #if (AMR == 1)
+ − #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − SIG_ONLY_MODE,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type,
+ − #if !FF_L1_IT_DSP_DTX
+ − 0, 0, 0, 0, 0, 0);
+ − #else
+ − 0, 0, 0, 0, 0, 0, 0);
+ − #endif
+ − #else
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − SIG_ONLY_MODE,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type,
+ − #if !FF_L1_IT_DSP_DTX
+ − 0, 0, 0, 0);
+ − #else
+ − 0, 0, 0, 0, 0);
+ − #endif
+ − #endif
+ − #else
+ − #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − SIG_ONLY_MODE,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type,
+ − #if !FF_L1_IT_DSP_DTX
+ − 0, 0, 0, 0, 0);
+ − #else
+ − 0, 0, 0, 0, 0, 0);
+ − #endif
+ − #else
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − SIG_ONLY_MODE,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type,
+ − #if !FF_L1_IT_DSP_DTX
+ − 0, 0, 0);
+ − #else
+ − 0, 0, 0, 0);
+ − #endif
+ − #endif
+ − #endif
+ − // for SDCCH we use DPAGC algorithm.
+ − #if DPAGC_MAX_FLAG
+ − agc = Cust_get_agc_from_IL(rx_radio_freq, IL_info_ptr->input_level >> 1, MAX_ID);
+ − #else
+ − agc = Cust_get_agc_from_IL(rx_radio_freq, IL_info_ptr->input_level >> 1, AV_ID);
+ − #endif
+ − lna_off = IL_info_ptr->lna_off;
+ −
+ −
+ −
+ − // Store input_level and lna_off field used for current CTRL in order to be able to build IL
+ − // from pm in READ phase.
+ − l1a_l1s_com.Scell_used_IL = *IL_info_ptr;
+ − } // end if (task == DDL) || (task == ADL)
+ − else
+ − {
+ − rx_radio_freq = l1a_l1s_com.Scell_info.radio_freq;
+ −
+ − // Catch training sequence code from serving cell BCC (part of BSIC).
+ − tsc = l1a_l1s_com.Scell_info.bsic & 0x0007;
+ −
+ − // for PCH/E_PCH/Serving BCCH and All CCCH we use
+ − // PAGC algorithm.
+ − #if 1 /* FreeCalypso match TCS211 */
+ −
+ − agc = Cust_get_agc_from_IL(rx_radio_freq, l1a_l1s_com.last_input_level[rx_radio_freq - l1_config.std.radio_freq_index_offset].input_level >> 1, MAX_ID);
+ − lna_off = l1a_l1s_com.last_input_level[rx_radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+ −
+ − // Store input_level and lna_off fields used for current CTRL in order to be able
+ − // to build IL from pm in READ phase.
+ − l1a_l1s_com.Scell_used_IL = l1a_l1s_com.last_input_level[rx_radio_freq - l1_config.std.radio_freq_index_offset];
+ −
+ − #elif (L1_FF_MULTIBAND == 0)
+ −
+ − input_level = l1a_l1s_com.last_input_level[rx_radio_freq - l1_config.std.radio_freq_index_offset].input_level ;
+ − lna_off = l1a_l1s_com.last_input_level[rx_radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+ − agc = Cust_get_agc_from_IL(rx_radio_freq, input_level >> 1, MAX_ID);
+ −
+ −
+ − // Store input_level and lna_off fields used for current CTRL in order to be able
+ − // to build IL from pm in READ phase.
+ − l1a_l1s_com.Scell_used_IL = l1a_l1s_com.last_input_level[rx_radio_freq - l1_config.std.radio_freq_index_offset];
+ −
+ − #else // L1_FF_MULTIBAND = 1 below
+ −
+ − operative_radio_freq =
+ − l1_multiband_radio_freq_convert_into_operative_radio_freq(rx_radio_freq);
+ −
+ − input_level = l1a_l1s_com.last_input_level[operative_radio_freq].input_level ;
+ − lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+ − agc = Cust_get_agc_from_IL(rx_radio_freq, input_level >> 1, MAX_ID);
+ −
+ −
+ − // Store input_level and lna_off fields used for current CTRL in order to be able
+ − // to build IL from pm in READ phase.
+ − l1a_l1s_com.Scell_used_IL = l1a_l1s_com.last_input_level[operative_radio_freq];
+ −
+ −
+ − #endif // #if (L1_FF_MULTIBAND == 0) else
+ −
+ −
+ − }
+ −
+ − #if(RF_FAM == 61) // Locosto DCO
+ − cust_get_if_dco_ctl_algo(&dco_algo_ctl_nb, &if_ctl, (UWORD8) L1_IL_VALID ,
+ − input_level,
+ − rx_radio_freq,if_threshold);
+ − l1ddsp_load_dco_ctl_algo_nb(dco_algo_ctl_nb);
+ − #endif //RF_FAM =61
+ −
+ − #if (L1_SAIC != 0)
+ − // If SAIC is enabled, call the low level SAIC control function
+ − csf_filter_choice = l1ctl_saic(l1a_l1s_com.Scell_used_IL.input_level,l1a_l1s_com.mode
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,task
+ − ,&saic_flag
+ − #endif
+ − );
+ − #endif //L1_SAIC != 0
+ −
+ − // ADC measurement
+ − // ***************
+ − // check if during the 1st burst of the bloc an ADC measurement must be performed
+ − if ((burst_id == BURST_1) && (task == NP))
+ − {
+ − #if L1_GPRS
+ − //In case of network mode of operation II or III, CCCH reading is possible
+ − //in packet idle mode and in packet transfer mode.
+ − //ADC measurements are already managed by comlex function of Packet idle tasks
+ − if (!((l1a_l1s_com.l1s_en_task[PNP] == TASK_ENABLED) ||
+ − (l1a_l1s_com.l1s_en_task[PEP] == TASK_ENABLED) ||
+ − (l1a_l1s_com.l1s_en_task[PALLC] == TASK_ENABLED) ||
+ − (l1a_l1s_com.l1s_en_task[PDTCH] == TASK_ENABLED) ||
+ − (l1a_l1s_com.l1s_en_task[SINGLE] == TASK_ENABLED)))
+ − #endif
+ − {
+ − adc_active = l1s_ADC_decision_on_NP();
+ − }
+ − } // end if (burst_id == BURST_1) && (task == NP)
+ −
+ − if (task == ADL)
+ − {
+ − // ADC measurement for SACCH DL
+ − // ****************************
+ −
+ − // check if during the SACCH burst an ADC measurement must be performed
+ − if (l1a_l1s_com.adc_mode & ADC_NEXT_TRAFFIC_DL) // perform ADC only one time
+ − {
+ − adc_active = ACTIVE;
+ − l1a_l1s_com.adc_mode &= ADC_MASK_RESET_TRAFFIC; // reset in order to have only one ADC measurement in Traffic
+ − }
+ − else
+ − if (l1a_l1s_com.adc_mode & ADC_EACH_TRAFFIC_DL) // perform ADC on each period bloc
+ − {
+ − if ((++l1a_l1s_com.adc_cpt)>=l1a_l1s_com.adc_traffic_period) // wait for the period
+ − {
+ − adc_active = ACTIVE;
+ − l1a_l1s_com.adc_cpt = 0;
+ − }
+ − }
+ − }
+ −
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+ − #endif
+ −
+ − #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+ − trace_fct(CST_L1S_CTRL_SNB_DL_BURST0 + burst_id, (UWORD32)(-1));//OMAPS00090550
+ − #endif
+ −
+ − #if (TRACE_TYPE==5)
+ − trace_fct(CST_L1S_CTRL_SNB_DL, rx_radio_freq);
+ − #endif
+ −
+ − l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+ −
+ − // the l1a_l1s_com.mode variable could change during the block: So test this variable only on the 1st block
+ − // See BUG2237 (mode change from Idle to Transfert during BCCHS task)
+ − #if (L1_GPRS)
+ − if (burst_id == BURST_1)
+ − BCCHS_in_transfert = ((l1a_l1s_com.mode == PACKET_TRANSFER_MODE) && ((task == EBCCHS) || (task == NBCCHS)));
+ − #endif
+ −
+ − // Programs DSP according to the DSP scheduler used
+ − // *************************************************
+ −
+ −
+ − #if (L1_GPRS)
+ − switch(l1a_l1s_com.dsp_scheduler_mode)
+ − {
+ − // dsp pgm is made using GSM scheduler...
+ − case GSM_SCHEDULER:
+ − #if (FF_L1_FAST_DECODING == 1)
+ − l1ddsp_load_fast_dec_task(task,burst_id);
+ − #endif
+ − dsp_task = l1s_swap_iq_dl(rx_radio_freq,task);
+ − l1ddsp_load_rx_task(dsp_task, burst_id, tsc);
+ − break;
+ −
+ − // dsp pgm is made using GPRS scheduler...
+ − case GPRS_SCHEDULER:
+ − #if (FF_L1_FAST_DECODING == 1)
+ − l1ddsp_load_fast_dec_task(task,burst_id);
+ − #endif
+ − #if FF_L1_IT_DSP_USF
+ − l1pddsp_idle_rx_nb(burst_id,tsc,rx_radio_freq,0,FALSE,FALSE);
+ − #else
+ − l1pddsp_idle_rx_nb(burst_id,tsc,rx_radio_freq,0,FALSE);
+ − #endif
+ − break;
+ − }
+ − #else
+ − #if (FF_L1_FAST_DECODING == 1)
+ − l1ddsp_load_fast_dec_task(task,burst_id);
+ − #endif
+ − dsp_task = l1s_swap_iq_dl(rx_radio_freq,task);
+ − l1ddsp_load_rx_task(dsp_task, burst_id, tsc);
+ − #endif
+ −
+ − // update the TPU with the new TOA if necessary
+ − l1ctl_update_TPU_with_toa();
+ −
+ − // Programs TPU for required task.
+ − // ********************************
+ − #if (L1_GPRS)
+ −
+ − //In case of network mode of operation II or III, CCCH reading is possible
+ − //in packet idle mode and in packet transfer mode.
+ − // if (TS(CCCH) - TS(current task))%8 >= 4 synchro change is required
+ − // if not, OFFSET change is required
+ − //
+ − if (((task == EP) || (task == NP)) &&
+ − ((l1a_l1s_com.l1s_en_task[PNP] == TASK_ENABLED) ||
+ − (l1a_l1s_com.l1s_en_task[PEP] == TASK_ENABLED) ||
+ − (l1a_l1s_com.l1s_en_task[PALLC] == TASK_ENABLED) ||
+ − (l1a_l1s_com.l1s_en_task[PDTCH] == TASK_ENABLED) ||
+ − (l1a_l1s_com.l1s_en_task[SINGLE] == TASK_ENABLED)))
+ − {
+ − UWORD32 new_offset;
+ − WORD32 new_synchro;
+ − UWORD32 ts_ccch;
+ −
+ − ts_ccch = (l1a_l1s_com.ccch_group * 2); //timeslot CCCH burts
+ − new_offset = (ts_ccch - l1a_l1s_com.dl_tn + 8) % 8; //dl_tn is the current time slot from previous task
+ −
+ − if (burst_id == BURST_1)
+ − l1s.forbid_meas = TASK_ROM_MFTAB[task].size;
+ −
+ − if (new_offset >= 4)
+ − algo_change_synchro_active = TRUE;
+ −
+ − if (algo_change_synchro_active)
+ − {
+ − // compute TPU offset for "current timeslot + 4 timeslot"
+ − new_synchro = l1s.tpu_offset + (4 * TN_WIDTH);
+ −
+ − if(new_synchro >= TPU_CLOCK_RANGE)
+ − new_synchro -= TPU_CLOCK_RANGE;
+ −
+ − //compute new offset
+ − new_offset = (((ts_ccch + 4 - l1a_l1s_com.dl_tn)%8) * TN_WIDTH) + new_synchro;
+ − }
+ − //no synchro change required, but new offset is computed
+ − else
+ − {
+ − new_synchro = l1s.tpu_offset;
+ − new_offset = (new_offset * TN_WIDTH) + new_synchro;
+ − }
+ −
+ − if (new_offset >= TPU_CLOCK_RANGE)
+ − new_offset -= TPU_CLOCK_RANGE;
+ −
+ − // tpu pgm...
+ − l1dtpu_serv_rx_nb(rx_radio_freq,
+ − agc,
+ − lna_off,
+ − new_synchro,
+ − new_offset,
+ − TRUE,
+ − adc_active
+ − #if (RF_FAM == 61)
+ − ,csf_filter_choice
+ − ,if_ctl
+ − #endif
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,saic_flag
+ − #endif /*NEW_SNR_THRESHOLD */
+ − );
+ − } // end if (task == EP) || (task == NP) in packet Idle
+ −
+ − // in case of EBCCHS and NBCCHS in packet transfer a change synchro is performed
+ − else if (BCCHS_in_transfert)
+ − {
+ − UWORD32 new_offset;
+ − WORD32 new_synchro;
+ −
+ − change_synchro = ((l1a_l1s_com.dl_tn > 0) && (l1a_l1s_com.dl_tn < 5 ));
+ −
+ − // if change synchro is needed
+ − if(change_synchro) // TS= [1,2,3,4]
+ − {
+ − // the synchro is changed by 4 timeslots.
+ − new_synchro = l1s.tpu_offset + (4 * TN_WIDTH);
+ − if(new_synchro >= TPU_CLOCK_RANGE)
+ − new_synchro -= TPU_CLOCK_RANGE;
+ −
+ − // the TPU offset is changed according to the PDTCH time slot
+ − // because of the new synchro above with a shift of 4TS,
+ − // 4TS are substract to the offset
+ − new_offset = (8 - 4 - l1a_l1s_com.dl_tn) * TN_WIDTH;
+ − }
+ − else
+ − {
+ − // the synchro is unchanged
+ − new_synchro = l1s.tpu_offset;
+ −
+ − // the TPU offset is changed according to the PDTCH time slot
+ − new_offset = (8 - l1a_l1s_com.dl_tn) * TN_WIDTH;
+ − }
+ −
+ − new_offset += new_synchro;
+ − if (new_offset >= TPU_CLOCK_RANGE)
+ − new_offset -= TPU_CLOCK_RANGE;
+ −
+ − // tpu pgm...
+ − #if (RF_FAM == 61)
+ − l1dtpu_serv_rx_nb(rx_radio_freq,
+ − agc,
+ − lna_off,
+ − new_synchro,
+ − new_offset,
+ − TRUE,
+ − adc_active,
+ − csf_filter_choice,
+ − if_ctl
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,saic_flag
+ − #endif /*NEW_SNR_THRESHOLD */
+ − );
+ − #endif
+ −
+ − #if(RF_FAM != 61)
+ − l1dtpu_serv_rx_nb(rx_radio_freq,
+ − agc,
+ − lna_off,
+ − new_synchro,
+ − new_offset,
+ − TRUE,
+ − adc_active);
+ − #endif
+ −
+ − } // end if (task == EBCCHS) || (task == NBCCHS) in packet Idle
+ − else
+ − #endif
+ − {
+ − // tpu pgm...
+ − #if (RF_FAM == 61)
+ − l1dtpu_serv_rx_nb(rx_radio_freq,
+ − agc,
+ − lna_off,
+ − l1s.tpu_offset,
+ − l1s.tpu_offset,
+ − FALSE,
+ − adc_active,
+ − csf_filter_choice,
+ − if_ctl
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,saic_flag
+ − #endif /*NEW_SNR_THRESHOLD */
+ − );
+ − #endif
+ − #if (RF_FAM != 61)
+ − l1dtpu_serv_rx_nb(rx_radio_freq,
+ − agc,
+ − lna_off,
+ − l1s.tpu_offset,
+ − l1s.tpu_offset,
+ − FALSE,
+ − adc_active);
+ − #endif
+ − }
+ −
+ − // Increment tpu window identifier.
+ − l1s.tpu_win += (l1_config.params.rx_synth_load_split + RX_LOAD);
+ −
+ − // GSM DSP scheduler is not able to handle PWR too close to RX normal burst.
+ − // We have to oblige a min of 1 burst period between RX and PWR
+ − if(l1_config.params.rx_synth_load_split < BP_SPLIT)
+ − l1s.tpu_win += BP_SPLIT - l1_config.params.rx_synth_load_split;
+ −
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET_NEIGH)
+ − buffer_trace(4, l1s.actual_time.fn, rx_radio_freq,
+ − l1s.tpu_win,l1s.tpu_offset);
+ − #endif
+ − #endif
+ − }
+ −
+ − #if (L1_GPRS)
+ −
+ − //In case of network mode of operation II or III, CCCH reading is possible
+ − //in packet idle mode and in packet transfer mode.
+ −
+ − if (((task == EP) || (task == NP)) &&
+ − ((l1a_l1s_com.l1s_en_task[PNP] == TASK_ENABLED) ||
+ − (l1a_l1s_com.l1s_en_task[PEP] == TASK_ENABLED) ||
+ − (l1a_l1s_com.l1s_en_task[PALLC] == TASK_ENABLED) ||
+ − (l1a_l1s_com.l1s_en_task[PDTCH] == TASK_ENABLED) ||
+ − (l1a_l1s_com.l1s_en_task[SINGLE] == TASK_ENABLED)))
+ − {
+ − if((burst_id == BURST_4) && algo_change_synchro_active)
+ − {
+ −
+ − // Slide synchro back to mach current serving timeslot.
+ − l1dmacro_synchro(SWITCH_TIME, l1s.tpu_offset);
+ −
+ −
+ − // Increment frame number.
+ − l1s.actual_time = l1s.next_time;
+ − l1s.next_time = l1s.next_plus_time;
+ − l1s_increment_time (&(l1s.next_plus_time), 1); // Increment "next_plus time".
+ −
+ − l1s.tpu_ctrl_reg |= CTRL_SYCB;
+ − l1s.dsp_ctrl_reg |= CTRL_SYNC;
+ − l1s.ctrl_synch_before = FALSE;
+ − algo_change_synchro_active = FALSE;
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − trace_fct(CST_L1S_ADJUST_TIME, (UWORD32)(-1));//OMAPS00090550
+ − #endif
+ − }
+ − }
+ −
+ − // in case of EBCCHS and NBCCHS in packet transfer a change synchro is performed
+ − else if (BCCHS_in_transfert)
+ − {
+ − // Shift TPU SYNCHRO/OFFSET registers back to the default timeslot .
+ − // ****************************************************************
+ − // When the E/NBCCHS reading control is completed ,
+ − // the SYNCHRO/OFFSET registers are shifted back to the normal
+ − // setting used for PCCH reading on the serving cell.
+ − // Check if "Synchro" change was needed.
+ − // If so the synchro is changed to recover normal synchro.
+ − if(burst_id == BURST_4)
+ − {
+ − if(change_synchro) // TS= [1,2,3,4]
+ − {
+ − // Slide synchro back to mach current serving timeslot.
+ − l1dmacro_synchro(SWITCH_TIME, l1s.tpu_offset);
+ −
+ − // Increment frame number.
+ − l1s.actual_time = l1s.next_time;
+ − l1s.next_time = l1s.next_plus_time;
+ − l1s_increment_time(&(l1s.next_plus_time), 1); // Increment "next_plus time".
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − trace_fct(CST_L1S_ADJUST_TIME, (UWORD32)(-1));//OMAPS00090550
+ − #endif
+ −
+ − l1s.tpu_ctrl_reg |= CTRL_SYCB;
+ − l1s.dsp_ctrl_reg |= CTRL_SYNC;
+ − }
+ − }
+ −
+ − // This task is not compatible with Neigh. Measurement. Store task length
+ − // in "forbid_meas" to indicate when the task will last.
+ − if(burst_id == BURST_1)
+ − l1s.forbid_meas = TASK_ROM_MFTAB[task].size;
+ − }
+ − #endif
+ −
+ − // Flag the reading of a Normal Paging burst.
+ − // *******************************************
+ −
+ − // Set flag "NP contoled !!". Used in "l1_synch()" to generate meas. controles.
+ − if(task == NP)
+ − l1a_l1s_com.ba_list.np_ctrl = burst_id+1;
+ −
+ − // Flag DSP and TPU programmation.
+ − // ********************************
+ −
+ − // Set "CTRL_RX" flag in the controle flag register.
+ − l1s.tpu_ctrl_reg |= CTRL_RX;
+ − l1s.dsp_ctrl_reg |= CTRL_RX;
+ − }
+ −
+ − //#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END
+ − #endif
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_snb_ul() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* serving cell normal burst sending tasks: DUL, AUL. */
+ − /* This function is the control function for sending a */
+ − /* burst on a SDCCH channel. It programs the DSP and the */
+ − /* TPU for sending a normal burst taking into account */
+ − /* the timing adavance. Here is a summary of the */
+ − /* execution: */
+ − /* */
+ − /* - Catch ARFCN. */
+ − /* - Traces and debug. */
+ − /* - Programs DSP for required task. */
+ − /* - Catch UL data block from DLL and gives it to DSP. */
+ − /* - Programs TPU for required task. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* DUL, SDCCH UPLINK sending task. */
+ − /* AUL, SACCH UPLINK (associated with SDCCH)sending */
+ − /* task. */
+ − /* */
+ − /* "burst_id" */
+ − /* BURST_1, 1st burst of the task. */
+ − /* BURST_2, 2nd burst of the task. */
+ − /* BURST_3, 3rd burst of the task. */
+ − /* BURST_4, 4th burst of the task. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.dedic_set" */
+ − /* Dedicated channel parameter structure. It is used */
+ − /* to get the ARFCN to use for SDCCH (DUL, AUL). This */
+ − /* ARFCN comes from the HOPPING algorithm called just */
+ − /* before calling this function. */
+ − /* */
+ − /* "l1a_l1s_com.Scell_info" */
+ − /* Serving cell information structure. */
+ − /* .bsic, BSIC of the serving cell. It is used here */
+ − /* to pass the training sequence number (part */
+ − /* of BSIC) to the DSP. */
+ − /* */
+ − /* "l1s.afc" */
+ − /* current AFC value to be applied for the given task. */
+ − /* */
+ − /* "l1s.tpu_offset" */
+ − /* value for the TPU SYNCHRO and OFFSET registers */
+ − /* for current serving cell setting. It is used here */
+ − /* to restore this value in the OFFSET register after */
+ − /* the TX burst programming. */
+ − /* */
+ − /* "l1s.applied_txpwr" */
+ − /* Applied transmit power. */
+ − /* */
+ − /* "l1s.reported_txpwr" */
+ − /* Transmit power to report in the L1 header of the */
+ − /* SACCH data block. */
+ − /* */
+ − /* "l1a_l1s_com.dedic_set.aset" */
+ − /* Active dedicated mode parameter set. */
+ − /* .timing_advance, Timing advance to apply to the UL */
+ − /* burst transmission. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.tpu_win" */
+ − /* each frame is composed with a maximum of 3 */
+ − /* working/TPU windows (typically RX/TX/PW). This is */
+ − /* a counter used to count the number of windows */
+ − /* used. */
+ − /* -> set to TDMA_WIN3. */
+ − /* */
+ − /* "l1s.tpu_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/TPU com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_TX bit in the register. */
+ − /* */
+ − /* "l1s.dsp_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/DSP com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_TX bit in the register. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_ctrl_snb_ul(UWORD8 task, UWORD8 burst_id)
+ − {
+ − T_RADIO_FRAME *tx_data = NULL;
+ − UWORD16 tx_radio_freq;
+ − UWORD32 dsp_task;
+ − UWORD8 adc_active_ul = INACTIVE;
+ −
+ − // Catch ARFCN.
+ − // *************
+ −
+ − // Get ARFCN to be used for current control.
+ − tx_radio_freq = l1a_l1s_com.dedic_set.radio_freq;
+ −
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+ − if(burst_id == BURST_1) trace_flowchart_dsptx(dltsk_trace[task].name);
+ − #endif
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_SNB_UL, tx_radio_freq);
+ − #endif
+ −
+ − l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+ −
+ − // Programs DSP for required task.
+ − // ********************************
+ −
+ − // Set CIPHERING reduced frame number.
+ − #if (AMR == 1)
+ − #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − SIG_ONLY_MODE,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type,
+ − #if !FF_L1_IT_DSP_DTX
+ − 0, 0, 0, 0, 0, 0);
+ − #else
+ − 0, 0, 0, 0, 0, 0, 0);
+ − #endif
+ − #else
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − SIG_ONLY_MODE,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type,
+ − #if !FF_L1_IT_DSP_DTX
+ − 0, 0, 0, 0);
+ − #else
+ − 0, 0, 0, 0, 0);
+ − #endif
+ − #endif
+ − #else
+ − #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − SIG_ONLY_MODE,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type,
+ − #if !FF_L1_IT_DSP_DTX
+ − 0, 0, 0, 0, 0);
+ − #else
+ − 0, 0, 0, 0, 0, 0);
+ − #endif
+ − #else
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − SIG_ONLY_MODE,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type,
+ − #if !FF_L1_IT_DSP_DTX
+ − 0, 0, 0);
+ − #else
+ − 0, 0, 0, 0);
+ − #endif
+ − #endif
+ − #endif
+ −
+ − if(task == DUL)
+ − // SDCCH/UL task.
+ − {
+ − if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send != 0)
+ − // "ho_acc_to_send" is a counter of Handover Access burst still to send.
+ − // This counter is set by "l1s_dedicated_mode_manager()" in L1S when a
+ − // Handover command is received from L3 through L1A.
+ − {
+ − // TX burst is a RACH.
+ − // ********************
+ − // dsp and tpu pgm...
+ − l1s_ctrl_rach(RAHO,NO_PAR);
+ −
+ − // Decrement number of HO ACCESS burst still to be sent.
+ − // Rem: (-1) is used for Async. HO.
+ − if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send != -1)
+ − l1a_l1s_com.dedic_set.aset->ho_acc_to_send --;
+ −
+ − if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send == 0)
+ − // Handover access procedure is completed.
+ − // -> send L1C_HANDOVER_FINISHED message with "cause = COMPLETED" to L1A.
+ − {
+ − l1s_send_ho_finished(HO_COMPLETE);
+ − }
+ − }
+ −
+ − else
+ − {
+ − // TX burst is a Normal Burst.
+ − // ****************************
+ − // dsp pgm...
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − RTTL1_FILL_UL_NB(task, l1a_l1s_com.dedic_set.aset->timing_advance, l1s.applied_txpwr)
+ − #endif
+ −
+ − dsp_task = l1s_swap_iq_ul(tx_radio_freq,task);
+ −
+ − l1ddsp_load_tx_task(dsp_task,
+ − burst_id,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->tsc);
+ −
+ − // tpu pgm...
+ − l1dtpu_serv_tx_nb(tx_radio_freq,
+ − l1a_l1s_com.dedic_set.aset->timing_advance,
+ − l1s.tpu_offset,
+ − l1s.applied_txpwr,INACTIVE);
+ −
+ − // Catch UL data block from DLL and gives it to DSP.
+ − // **************************************************
+ − // SDCCH info.
+ − if(burst_id == BURST_1)
+ − // perform "PH_DATA_REQ" from L2...
+ − {
+ − // Get SDCCH/UL data block from L2.
+ − tx_data = dll_read_dcch(SIG_ONLY_MODE);
+ −
+ − // Store the UL data block in MCU/DSP interface.
+ − if(tx_data != NULL) // NULL should never occur !!!
+ − {
+ − #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+ − RTTL1_FILL_UL_DCCH
+ − trace_info.facch_ul_count ++;
+ − #endif
+ −
+ − l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_cu, &(tx_data->A[0]));
+ − }
+ − }
+ − }
+ −
+ − // In any case set TXPWR.
+ − l1ddsp_load_txpwr(l1s.applied_txpwr, tx_radio_freq);
+ −
+ − } // End if(task == DUL)
+ −
+ − else
+ − // SACCH/UL task.
+ − {
+ −
+ − if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send != 0)
+ − // "ho_acc_to_send" is a counter of Handover Access burst still to send.
+ − // This counter is set by "l1s_dedicated_mode_manager()" in L1S when a
+ − // Handover command is received from L3 through L1A.
+ − // Rem: it is not allowed to send HO ACCESS burst on SACCH/UL. We must
+ − // then avoid any normal burst transmission by setting txpwr=NO_TXPWR. The DSP
+ − // and TPU are controled normally.
+ − {
+ − // Set TXPWR.
+ − l1ddsp_load_txpwr(NO_TXPWR, tx_radio_freq);
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − RTTL1_FILL_UL_NB(task, l1a_l1s_com.dedic_set.aset->timing_advance, NO_TXPWR)
+ − #endif
+ − }
+ −
+ − else
+ − {
+ − // Set TXPWR.
+ − l1ddsp_load_txpwr(l1s.applied_txpwr, tx_radio_freq);
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − RTTL1_FILL_UL_NB(task, l1a_l1s_com.dedic_set.aset->timing_advance, l1s.applied_txpwr)
+ − #endif
+ − }
+ −
+ − //ADC Measurements
+ − //
+ −
+ − // Check if during the SACCH burst an ADC measurement shall be performed
+ −
+ − if (l1a_l1s_com.adc_mode & ADC_NEXT_TRAFFIC_UL) // perform ADC only one time
+ − {
+ − adc_active_ul = ACTIVE;
+ − l1a_l1s_com.adc_mode &= ADC_MASK_RESET_TRAFFIC; // reset in order to have only one ADC measurement in Traffic
+ − }
+ − else
+ − {
+ − if (l1a_l1s_com.adc_mode & ADC_EACH_TRAFFIC_UL) // perform ADC on each period bloc
+ − {
+ − if ((++l1a_l1s_com.adc_cpt)>=l1a_l1s_com.adc_traffic_period) // wait for the period
+ − {
+ − adc_active_ul = ACTIVE;
+ − l1a_l1s_com.adc_cpt = 0;
+ − }
+ − }
+ − }
+ −
+ −
+ − // In any case TX burst is a Normal Burst.
+ − // ****************************************
+ − // dsp pgm...
+ −
+ − dsp_task = l1s_swap_iq_ul(tx_radio_freq,task);
+ −
+ − l1ddsp_load_tx_task(dsp_task,
+ − burst_id,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->tsc);
+ −
+ − // tpu pgm...
+ − l1dtpu_serv_tx_nb(tx_radio_freq,
+ − l1a_l1s_com.dedic_set.aset->timing_advance,
+ − l1s.tpu_offset,
+ − l1s.applied_txpwr,adc_active_ul);
+ −
+ −
+ − // Catch UL data block from DLL and gives it to DSP.
+ − // **************************************************
+ − // SACCH info.
+ − if(burst_id == BURST_1)
+ − // perform "PH_DATA_REQ" from L2...
+ − {
+ −
+ − #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+ − BOOL tx_data_flag = FALSE; //omaps00090550
+ − #endif
+ −
+ − #if (FF_REPEATED_SACCH == 1)
+ − #if TESTMODE
+ − if(l1_config.repeat_sacch_enable != REPEATED_SACCH_ENABLE) /* disable the repeated sacch mode */
+ − {
+ − l1s.repeated_sacch.sro = 0; /* set no repetition order */
+ − l1s.repeated_sacch.buffer_empty = TRUE; /* set no buffer */
+ − }
+ − #endif /* TESTMODE */
+ − #endif /* (FF_REPEATED_SACCH == 1) */
+ − #if (FF_REPEATED_SACCH == 1)
+ − /* Get data from PS if only no repetition order is required (1st condition)
+ − or no repetition candidate exists (2nd condition) */
+ − if( (l1s.repeated_sacch.sro == 0) || (l1s.repeated_sacch.buffer_empty == TRUE) )
+ − {
+ − #endif /* (FF_REPEATED_SACCH == 1) */
+ − tx_data = dll_read_sacch(SIG_ONLY_MODE);
+ −
+ − if(tx_data != NULL) // NULL should never occur !!!
+ − {
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − tx_data_flag =TRUE; //omaps00090550
+ − #endif
+ − // Set L1 Header...
+ − tx_data->A[0] = l1s.reported_txpwr;
+ − #if (FF_REPEATED_SACCH == 1)
+ − /* Include the SACCH Repetition Request (SRR) in the L1 Header */
+ − tx_data->A[0] |= (l1s.repeated_sacch.srr <<6);
+ −
+ − #endif /* FF_REPEATED_SACCH */
+ − tx_data->A[1] = l1a_l1s_com.dedic_set.aset->timing_advance;
+ −
+ − // Store the UL data block in MCU/DSP interface.
+ − l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_cu, &(tx_data->A[0]));
+ − #if (FF_REPEATED_SACCH == 1 )
+ − /* Store the block data in case of a retransmission order */
+ − /* Retransmission is done in case of a SAPI0 and not 3 */
+ − if(((tx_data->A[2]&0x1C) >> 2) == SAPI_0)
+ − {
+ − l1s_store_sacch_buffer( &(l1s.repeated_sacch), &(tx_data->A[0]));
+ − }
+ − else // FIXME FIXME NOT sure whether this needs to be done
+ − {
+ − /* the SACCH repetition block occurrence will always come as a consecutive pair */
+ − /* To handle DL UL | DL UL | DL UL */
+ − /* - 0 | SRO 3 | - new data should be asked from PS old 0 cannot be repeated */
+ − l1s.repeated_sacch.buffer_empty=TRUE;
+ − }
+ − #endif /* FF_REPEATED_SACCH */
+ −
+ − }/* end of if(tx_data != NULL) */
+ − #if (FF_REPEATED_SACCH == 1)
+ − }
+ −
+ − else if ((l1s.repeated_sacch.sro == 1) && (l1s.repeated_sacch.buffer_empty == FALSE))
+ − {
+ − /* Put data block in MCU/DSP com. */
+ − l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_cu, l1s.repeated_sacch.buffer );
+ − l1s.repeated_sacch.buffer_empty = TRUE; /* Set that the buffer is now empty (only one repetition) */
+ − }
+ − #endif /* FF_REPEATED_SACCH */
+ −
+ − #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+ − RTTL1_FILL_UL_SACCH(tx_data_flag,l1a_l1s_com.dedic_set.aset->timing_advance, l1s.reported_txpwr) //omaps00090550
+ − #endif
+ −
+ − }
+ − }
+ −
+ − // Set tpu window identifier for Power meas after TX.
+ − l1s.tpu_win = (3 * BP_SPLIT) + l1_config.params.tx_nb_load_split + l1_config.params.rx_synth_load_split;
+ −
+ − // Flag DSP and TPU programmation.
+ − // ********************************
+ −
+ − // Set "CTRL_TX" flag in the controle flag register.
+ − l1s.tpu_ctrl_reg |= CTRL_TX;
+ − l1s.dsp_ctrl_reg |= CTRL_TX;
+ − }
+ −
+ − #if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_nnb() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* neigbor cell normal burst reading tasks: BCCHN. */
+ − /* This function is the control function for reading 4 */
+ − /* normal bursts on a neighbor cell. It programs the DSP */
+ − /* and the TPU for reading the 4 bursts taking into */
+ − /* account the time difference between the serving and */
+ − /* the neighbor cells. To this avail, it shifts the TPU */
+ − /* OFFSET register according to this time difference and */
+ − /* restores the serving offset value when the 4 burst */
+ − /* reading are completed. Here is a summary of the */
+ − /* execution: */
+ − /* */
+ − /* - If SEMAPHORE(task) is low. */
+ − /* - Traces and debug. */
+ − /* - Programs DSP for required task. */
+ − /* - Programs TPU for required task. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* BCCHN, BCCH Neighbor reading task. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.Ncell_info.bcch" */
+ − /* cell information structure used for BCCHN task. */
+ − /* */
+ − /* "l1a_l1s_com.l1s_en_task" */
+ − /* L1S task enable bit register. Used here to check if */
+ − /* the Full BCCH Reading task is enabled and then to */
+ − /* take the decision to reloading the serving value */
+ − /* in the TPU OFFSET register. */
+ − /* */
+ − /* "l1s.tpu_offset" */
+ − /* value for SYNCHRO and OFFSET register in the TPU */
+ − /* for current serving cell setting. At the end of */
+ − /* the task this value is restored in the OFFSET */
+ − /* register. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.tpu_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/TPU com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /* "l1s.dsp_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/DSP com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_ctrl_nnb(UWORD8 task, UWORD8 param2)
+ − {
+ − UWORD8 lna_off;
+ − WORD8 agc;
+ − T_NCELL_SINGLE *cell_info_ptr = NULL;
+ − BOOL en_task;
+ − BOOL task_param;
+ − UWORD32 dsp_task;
+ − #if(L1_FF_MULTIBAND == 1)
+ − UWORD16 operative_radio_freq;
+ − UWORD8 input_level;
+ − #endif
+ −
+ − #if (RF_FAM == 61)
+ − UWORD16 dco_algo_ctl_nb = 0;
+ − UWORD8 if_ctl = 0;
+ − UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+ − #endif
+ −
+ − // Get "enable" task flag and "synchro semaphore" for current task.
+ − en_task = l1a_l1s_com.l1s_en_task[task];
+ − task_param = l1a_l1s_com.task_param[task];
+ −
+ −
+ −
+ − if((en_task) && !(task_param))
+ − // Check the task semaphore and enable flag. The control body is executed only
+ − // when the task semaphore is 0 and enable flag is 1. The semaphore can be set to
+ − // 1 whenever L1A makes some changes to the task parameters. The enable can be
+ − // reset to 0 when the task is no more enabled.
+ − {
+ − // Get the cell information structure.
+ − // ************************************
+ − if (task == BCCHN)
+ − cell_info_ptr = &l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_norm];
+ − else // BCCHN_TOP and BCCHN_TRAN tasks
+ − cell_info_ptr = &l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_top];
+ −
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_NNB, cell_info_ptr->radio_freq);
+ − #endif
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+ − #endif
+ −
+ − l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 6) ;
+ −
+ − // Programs DSP for required task.
+ − // ********************************
+ −
+ − #if L1_GPRS
+ − switch(l1a_l1s_com.dsp_scheduler_mode)
+ − {
+ − // dsp pgm is made using GSM scheduler...
+ − case GSM_SCHEDULER:
+ − dsp_task = l1s_swap_iq_dl(cell_info_ptr->radio_freq,task);
+ − l1ddsp_load_rx_task(dsp_task,
+ − 0,
+ − cell_info_ptr->tsc);
+ − break;
+ −
+ − // dsp pgm is made using GPRS scheduler...
+ − case GPRS_SCHEDULER:
+ − l1pddsp_load_bcchn_task(cell_info_ptr->tsc, cell_info_ptr->radio_freq);
+ − break;
+ − }
+ − #else
+ − // dsp pgm...
+ − dsp_task = l1s_swap_iq_dl(cell_info_ptr->radio_freq,task);
+ − l1ddsp_load_rx_task(dsp_task,
+ − 0,
+ − cell_info_ptr->tsc);
+ − #endif
+ −
+ − // Programs TPU for required task.
+ − // ********************************
+ −
+ − // We program 4 burst reading. The OFFSET register is used to
+ − // cope with the time difference between the serving and the
+ − // neighbor cells. The serving cell offset value (l1s.tpu_offset)
+ − // is restored at the end of the 4 burst reading.
+ − #if (L1_FF_MULTIBAND == 0)
+ −
+ − // agc is computed from PGC2 algo result.
+ − agc = Cust_get_agc_from_IL(cell_info_ptr->radio_freq, l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].input_level >> 1, AV_ID);
+ − lna_off = l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+ −
+ − #else // L1_FF_MULTIBAND = 1 below
+ −
+ − operative_radio_freq =
+ − l1_multiband_radio_freq_convert_into_operative_radio_freq(cell_info_ptr->radio_freq);
+ − lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+ − input_level = l1a_l1s_com.last_input_level[operative_radio_freq].input_level;
+ − // agc is computed from PGC2 algo result.
+ − agc = Cust_get_agc_from_IL(cell_info_ptr->radio_freq, l1a_l1s_com.last_input_level[operative_radio_freq].input_level >> 1, AV_ID);
+ −
+ − #endif // #if (L1_FF_MULTIBAND == 0) else
+ −
+ −
+ −
+ − #if(RF_FAM == 61) // Locosto DCO
+ − cust_get_if_dco_ctl_algo(&dco_algo_ctl_nb, &if_ctl, (UWORD8) L1_IL_VALID,
+ − #if (L1_FF_MULTIBAND == 0)
+ − l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].input_level,
+ − #else
+ − input_level,
+ − #endif
+ − cell_info_ptr->radio_freq,if_threshold);
+ −
+ − //dco_algo_ctl has 0000 00ZL
+ − dco_algo_ctl_nb *= 0x55; // replicate 0000 00zL as ZLZL ZLZL
+ −
+ − l1ddsp_load_dco_ctl_algo_nb(dco_algo_ctl_nb);
+ − #endif
+ −
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET_NEIGH)
+ − buffer_trace(4, l1s.actual_time.fn, cell_info_ptr->radio_freq,
+ − cell_info_ptr->time_alignmt, cell_info_ptr->fn_offset);
+ − #endif
+ − #endif
+ −
+ − #if (RF_FAM == 61)
+ − if ( cell_info_ptr->time_alignmt >= TPU_CLOCK_RANGE - EPSILON_SYNC)
+ − {
+ − // Insert 1 NOP to correct the EPSILON_SYNC side effect
+ − l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+ − agc,
+ − lna_off,
+ − cell_info_ptr->time_alignmt,
+ − l1s.tpu_offset,
+ − FALSE, 1,
+ − if_ctl
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,SAIC_OFF
+ − #endif /* NEW_SNR_THRESHOLD == 1*/
+ − );
+ − }
+ − else
+ − {
+ − l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+ − agc,
+ − lna_off,
+ − cell_info_ptr->time_alignmt,
+ − l1s.tpu_offset,
+ − FALSE, 0,
+ − if_ctl
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,SAIC_OFF
+ − #endif /* NEW_SNR_THRESHOLD == 1*/
+ − );
+ − }
+ −
+ − l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+ − agc,
+ − lna_off,
+ − cell_info_ptr->time_alignmt,
+ − l1s.tpu_offset,
+ − FALSE, 0,
+ − if_ctl
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,SAIC_OFF
+ − #endif /* NEW_SNR_THRESHOLD == 1*/
+ − );
+ − l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+ − agc,
+ − lna_off,
+ − cell_info_ptr->time_alignmt,
+ − l1s.tpu_offset,
+ − FALSE, 0,
+ − if_ctl
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,SAIC_OFF
+ − #endif /* NEW_SNR_THRESHOLD == 1*/
+ − );
+ − l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+ − agc,
+ − lna_off,
+ − cell_info_ptr->time_alignmt,
+ − l1s.tpu_offset,
+ − TRUE, 0,
+ − if_ctl
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,SAIC_OFF
+ − #endif /* NEW_SNR_THRESHOLD == 1*/
+ − );
+ − #endif // RF_FAM == 61
+ −
+ − #if (RF_FAM != 61)
+ − if ( cell_info_ptr->time_alignmt >= TPU_CLOCK_RANGE - EPSILON_SYNC)
+ − {
+ − // Insert 1 NOP to correct the EPSILON_SYNC side effect
+ − l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+ − agc,
+ − lna_off,
+ − cell_info_ptr->time_alignmt,
+ − l1s.tpu_offset,
+ − FALSE, 1);
+ − }
+ − else
+ − {
+ − l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+ − agc,
+ − lna_off,
+ − cell_info_ptr->time_alignmt,
+ − l1s.tpu_offset,
+ − FALSE, 0);
+ − }
+ −
+ − l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+ − agc,
+ − lna_off,
+ − cell_info_ptr->time_alignmt,
+ − l1s.tpu_offset,
+ − FALSE, 0);
+ − l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+ − agc,
+ − lna_off,
+ − cell_info_ptr->time_alignmt,
+ − l1s.tpu_offset,
+ − FALSE, 0);
+ − l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+ − agc,
+ − lna_off,
+ − cell_info_ptr->time_alignmt,
+ − l1s.tpu_offset,
+ − TRUE, 0);
+ − #endif // RF_FAM != 61
+ − }
+ −
+ − // Flag DSP and TPU programmation.
+ − // ********************************
+ −
+ − // Set "CTRL_RX" flag in the controle flag register.
+ − l1s.tpu_ctrl_reg |= CTRL_RX;
+ − l1s.dsp_ctrl_reg |= CTRL_RX;
+ −
+ − #if L1_GPRS
+ − // This task is not compatible with Neigh. Measurement. Store task length
+ − // in "forbid_meas" to indicate when the task will last.
+ − if(task == BCCHN_TRAN)
+ − {
+ − // In IDLE mode, l1s.forbid_meas is setted by the AGC ctrl
+ − l1s.forbid_meas = TASK_ROM_MFTAB[task].size;
+ − }
+ − #endif
+ − }
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+ − #endif // MOVE_IN_INTERNAL_RAM
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_rach() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* serving cell Random Access burst sending tasks: RAAC, */
+ − /* RAHO. This function is the control function for */
+ − /* sending a random access burst to the serving cell. */
+ − /* This sending is either a Channel Request (connection */
+ − /* establishment) or a Handover Access burst (dedicated */
+ − /* mode). It programs the DSP and the TPU for sending a */
+ − /* random access burst with a null timing advance. */
+ − /* Here is a summary of the execution: */
+ − /* */
+ − /* - Traces and debug. */
+ − /* - Programs DSP for required task. */
+ − /* - Build RACH data block and store in MCU/DSP com. */
+ − /* - Programs TPU for required task. */
+ − /* - Send confirmation msg to L1A. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* RAAC, RACH sending task for Channel Request. */
+ − /* RAHO, RACH sending task for Handover Access. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.Scell_info" */
+ − /* Serving cell information structure. */
+ − /* .bsic, BSIC of the serving cell. It is used here */
+ − /* to pass the training sequence number (part */
+ − /* of BSIC) to the DSP. */
+ − /* .radio_freq, serving cell beacon frequency. */
+ − /* */
+ − /* "l1s.afc" */
+ − /* current AFC value to be applied for the given task. */
+ − /* */
+ − /* "l1s.tpu_offset" */
+ − /* value for the TPU SYNCHRO and OFFSET registers */
+ − /* for current serving cell setting. It is used here */
+ − /* to restore this value in the OFFSET register after */
+ − /* the TX burst programming. */
+ − /* */
+ − /* "l1s.applied_txpwr" */
+ − /* Applied transmit power. */
+ − /* */
+ − /* "l1a_l1s_com.ra_info" */
+ − /* random access task parameters. */
+ − /* .channel_request, random number sent in the case */
+ − /* of Channel Request (RAAC). */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.tpu_win" */
+ − /* each frame is composed with a maximum of 3 */
+ − /* working/TPU windows (typically RX/TX/PW). This is */
+ − /* a counter used to count the number of windows */
+ − /* used. */
+ − /* -> set to TDMA_WIN3. */
+ − /* */
+ − /* "l1s.tpu_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/TPU com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_TX bit in the register. */
+ − /* */
+ − /* "l1s.dsp_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/DSP com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_TX bit in the register. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_ctrl_rach(UWORD8 task, UWORD8 param2)
+ − {
+ − UWORD8 tx_data[2];
+ − UWORD16 radio_freq=0;
+ − UWORD32 dsp_task;
+ − UWORD8 adc_active=INACTIVE;
+ −
+ − // Get ARFCN to be used for current control.
+ − // *******************************************
+ −
+ − if(task == RAHO)
+ − // Handover Access...
+ − {
+ − // The ARFCN comes from the HOPPING algorithm called
+ − // prior to calling any CTRL function in the current frame.
+ − radio_freq = l1a_l1s_com.dedic_set.radio_freq;
+ − }
+ − else
+ − // Network Access...
+ − {
+ − #if TESTMODE
+ − if (l1_config.TestMode)
+ − {
+ − // A TX_TCH task has been enabled in TestMode with burst_type=access burst.
+ − // Thus set radio_freq to tch_arfcn .
+ − radio_freq = l1_config.tmode.rf_params.tch_arfcn;
+ − }
+ − else
+ − #endif
+ − {
+ − // The ARFCN is the BEACON frequency.
+ − radio_freq = l1a_l1s_com.Scell_info.radio_freq;
+ − }
+ − }
+ −
+ −
+ − // ADC measurement
+ − // ***************
+ −
+ − // check if during the RACH an ADC measurement must be performed
+ − if (task == RAACC)
+ − if (l1a_l1s_com.adc_mode & ADC_EACH_RACH) // perform ADC on each burst
+ − adc_active = ACTIVE;
+ −
+ −
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_RACH, radio_freq);
+ − #endif
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+ − #endif
+ −
+ − l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+ −
+ − #if (CODE_VERSION!=SIMULATION)
+ − #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+ − L1_trace_string("RA");
+ − #endif
+ − #endif
+ −
+ − // Programs DSP for required task.
+ − // ********************************
+ −
+ − // dsp pgm...
+ −
+ − dsp_task = l1s_swap_iq_ul(radio_freq,task);
+ −
+ − l1ddsp_load_ra_task(dsp_task);
+ −
+ − // Set TXPWR.
+ − l1ddsp_load_txpwr(l1s.applied_txpwr, radio_freq);
+ −
+ − // Build RACH data block and store in MCU/DSP com.
+ − // ************************************************
+ −
+ − // RACH info.
+ − if(task == RAACC)
+ − // RACH data is only the "channel_request". (BYTE format data).
+ − {
+ − tx_data[0] = (l1a_l1s_com.Scell_info.bsic << 2);
+ − tx_data[1] = l1a_l1s_com.ra_info.channel_request;
+ −
+ − }
+ − else
+ − // RACH data is only the "handover access" (BYTE format data).
+ − {
+ − tx_data[0] = (l1a_l1s_com.Scell_info.bsic << 2);
+ − tx_data[1] = l1a_l1s_com.dedic_set.aset->ho_acc;
+ − }
+ −
+ − // Store data block in MCU/DSP com.
+ − l1ddsp_load_info(DSP_TASK_CODE[task], &(l1s_dsp_com.dsp_ndb_ptr->d_rach), &(tx_data[0]));
+ −
+ − // Programs TPU for required task.
+ − // ********************************
+ −
+ − // tpu pgm...
+ − l1dtpu_serv_tx_ra(radio_freq, l1s.tpu_offset, l1s.applied_txpwr, adc_active);
+ −
+ − // Set tpu window identifier for Power meas if any.
+ − l1s.tpu_win = (3 * BP_SPLIT) + l1_config.params.tx_ra_load_split + l1_config.params.rx_synth_load_split;
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − RTTL1_FILL_UL_AB(task, l1s.applied_txpwr)
+ − #endif
+ −
+ − // Flag DSP and TPU programmation.
+ − // ********************************
+ −
+ − // Set "CTRL_TX" flag in the controle flag register.
+ − l1s.tpu_ctrl_reg |= CTRL_TX;
+ − l1s.dsp_ctrl_reg |= CTRL_TX;
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_tchtd() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: This function controls the non transmitting slot in case of Half Rate TCH */
+ − /* ------------ */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_ctrl_tchtd(UWORD8 task, UWORD8 param2)
+ − {
+ − T_CHANNEL_DESCRIPTION *desc_ptr;
+ − #if FF_L1_IT_DSP_DTX
+ − BOOL dtx_dsp_interrupt = FALSE;
+ − #endif
+ −
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsp_tpu(dltsk_trace[TCHD].name);
+ − #endif
+ −
+ − l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+ −
+ − // Catch channel description.
+ − // ***************************
+ −
+ − // Catch the active channel description used along the routine.
+ − // It contains:
+ − // "channel_type", {TCH_F, TCH_H, SDCCH_4, SDCCH_8}.
+ − // "subchannel", {0, 1}. 0 is the default value for TCH_F.
+ − desc_ptr = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr;
+ −
+ − /**************************************************************************/
+ − /* TCH/Dummy Receive... */
+ − /**************************************************************************/
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_TCHT_DUMMY__DL, l1a_l1s_com.dedic_set.radio_freq);
+ − #endif
+ −
+ − #if FF_L1_IT_DSP_DTX
+ − // Fast DTX active only in TCH AHS
+ − if ((l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_AHS_MODE)
+ − && (l1a_l1s_com.dedic_set.aset->dtx_allowed == TRUE))
+ − {
+ − // AHS0
+ − if (desc_ptr->subchannel == 0)
+ − {
+ − // DTX interrupt request for B1 and B2 (no DTX uncertainty on B0 thanks to idle frame)
+ − if (l1s.next_time.fn_mod13 <= 7)
+ − dtx_dsp_interrupt = TRUE;
+ − }
+ −
+ − // AHS1
+ − else
+ − {
+ − // DTX interrupt requested for ALL blocks (idle frame does not help)
+ − dtx_dsp_interrupt = TRUE;
+ − }
+ − }
+ − #endif
+ −
+ − /*--------------------------------------------*/
+ − /* Program DSP... */
+ − /*--------------------------------------------*/
+ − // dsp pgm.
+ − l1ddsp_load_rx_task(DSP_TASK_CODE[task], 0, desc_ptr->tsc);
+ −
+ − /*--------------------------------------------*/
+ − /* Flag DSP and TPU programmation... */
+ − /*--------------------------------------------*/
+ −
+ − // Set "CTRL_RX" flag in the controle flag register.
+ − l1s.dsp_ctrl_reg |= CTRL_RX;
+ −
+ −
+ − /*----------------------------------------------*/
+ − /* Common for Dedicated mode: DSP parameters... */
+ − /*----------------------------------------------*/
+ − #if (AMR == 1)
+ − #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+ − desc_ptr->channel_type,
+ − desc_ptr->subchannel,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+ − l1a_l1s_com.dedic_set.sync_tch,
+ − 0,
+ − l1a_l1s_com.dedic_set.reset_sacch,
+ − #if !FF_L1_IT_DSP_DTX
+ − l1a_l1s_com.dedic_set.vocoder_on);
+ − #else
+ − l1a_l1s_com.dedic_set.vocoder_on,
+ − dtx_dsp_interrupt);
+ − #endif
+ − #else
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+ − desc_ptr->channel_type,
+ − desc_ptr->subchannel,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+ − l1a_l1s_com.dedic_set.sync_tch,
+ − #if !FF_L1_IT_DSP_DTX
+ − 0);
+ − #else
+ − 0,
+ − dtx_dsp_interrupt);
+ − #endif
+ − #endif
+ − #else
+ − #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+ − desc_ptr->channel_type,
+ − desc_ptr->subchannel,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+ − l1a_l1s_com.dedic_set.sync_tch,
+ − l1a_l1s_com.dedic_set.reset_sacch,
+ − #if !FF_L1_IT_DSP_DTX
+ − l1a_l1s_com.dedic_set.vocoder_on);
+ − #else
+ − l1a_l1s_com.dedic_set.vocoder_on,
+ − dtx_dsp_interrupt);
+ − #endif
+ − #else
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+ − desc_ptr->channel_type,
+ − desc_ptr->subchannel,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+ − #if !FF_L1_IT_DSP_DTX
+ − l1a_l1s_com.dedic_set.sync_tch);
+ − #else
+ − l1a_l1s_com.dedic_set.sync_tch,
+ − dtx_dsp_interrupt);
+ − #endif
+ − #endif
+ − #endif
+ −
+ − // Clear "sync_tch" and "reset_sacch" flag to maintain normal TCH process.
+ − l1a_l1s_com.dedic_set.sync_tch = FALSE;
+ − #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+ − l1a_l1s_com.dedic_set.reset_sacch = FALSE;
+ − #endif
+ −
+ − // Set tpu window identifier for Power meas in case of dummy burst in Half-rate
+ − l1s.tpu_win = 0;
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_tchth() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* dedicated mode TCH task: TCHTH. This function is the */
+ − /* control function for reading the DL burst and sending */
+ − /* the UL burst. The UL burst can be a Normal Burst in */
+ − /* normal case or an Access Burst when starting a */
+ − /* Handover procedure. Both Half rate and Full rate TCH */
+ − /* channel are handled. The DSP and the TPU are */
+ − /* programmed for both the DL and UL bursts. The timing */
+ − /* advance is taken into account for positionning the UL */
+ − /* burst. */
+ − /* */
+ − /* This function accesses the L1/DLL and L1/DATA */
+ − /* interface ("dll_read_dcch()", "tx_tch_data()" */
+ − /* functions respectively) and passes then the returned */
+ − /* data blocks to the DSP. */
+ − /* */
+ − /* Here is a summary of the execution: */
+ − /* */
+ − /* - Traces and debug. */
+ − /* - Catch channel description and ARFCN. */
+ − /* - TCH/T Receive... */
+ − /* - Program DSP for RX. */
+ − /* - Program TPU for RX. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* - TCH/T Transmit... */
+ − /* - If Any Handover Access burst to send */
+ − /* - Call "l1s_ctrl_rach()". */
+ − /* - Else */
+ − /* - Get DATA block if required for TCH. */
+ − /* - Program DSP for TX. */
+ − /* - Program TPU for TX. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* - Common for DL/UL: DSP parameters. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* TCHTH, Traffic Channel TCH Half rate. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.dedic_set" */
+ − /* Dedicated channel parameter structure. */
+ − /* .radio_freq, ARFCN value set by the Hopping algo. */
+ − /* .aset, active dedicated parameter set. */
+ − /* */
+ − /* "l1a_l1s_com.Scell_info" */
+ − /* Serving cell information structure. */
+ − /* .bsic, BSIC of the serving cell. It is used here */
+ − /* to pass the training sequence number (part */
+ − /* of BSIC) to the DSP. */
+ − /* */
+ − /* "l1s.afc" */
+ − /* current AFC value to be applied for the given task. */
+ − /* */
+ − /* "l1s.tpu_offset" */
+ − /* value for the TPU SYNCHRO and OFFSET registers */
+ − /* for current serving cell setting. */
+ − /* */
+ − /* "l1s.applied_txpwr" */
+ − /* Applied transmit power. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.tpu_win" */
+ − /* each frame is composed with a maximum of 3 */
+ − /* working/TPU windows (typically RX/TX/PW). This is */
+ − /* a counter used to count the number of windows */
+ − /* used. */
+ − /* -> set to TDMA_WIN3. */
+ − /* */
+ − /* "l1s.tpu_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/TPU com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* -> set CTRL_TX bit in the register. */
+ − /* */
+ − /* "l1s.dsp_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/DSP com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* -> set CTRL_TX bit in the register. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_ctrl_tchth(UWORD8 task, UWORD8 param2)
+ − {
+ − UWORD16 radio_freq=0;
+ − T_CHANNEL_DESCRIPTION *desc_ptr;
+ − UWORD8 lna_off;
+ − WORD8 agc;
+ − T_INPUT_LEVEL *IL_info_ptr;
+ − UWORD32 dsp_task;
+ − UWORD32 fn_mod_52;
+ − UWORD8 input_level;
+ − #if (RF_FAM == 61)
+ − UWORD16 dco_algo_ctl_nb = 0;
+ − UWORD8 if_ctl = 0;
+ − UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+ − // By default we choose the hardware filter
+ − UWORD8 csf_filter_choice = L1_SAIC_HARDWARE_FILTER;
+ − #endif
+ − #if FF_L1_IT_DSP_DTX
+ − BOOL dtx_dsp_interrupt=FALSE; //omaps00090550
+ − #endif
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − UWORD8 saic_flag=0;
+ − #endif /* NEW_SNR_THRESHOLD */
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsp_tpu(dltsk_trace[TCHTH].name);
+ − #endif
+ −
+ − l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+ −
+ − // Catch channel description and ARFCN.
+ − // *************************************
+ −
+ − // Catch the active channel description used along the routine.
+ − // It contains:
+ − // "channel_type", {TCH_F, TCH_H, SDCCH_4, SDCCH_8}.
+ − // "subchannel", {0, 1}. 0 is the default value for TCH_F.
+ − desc_ptr = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr;
+ −
+ − // Get ARFCN to be used for current control. This ARFCN comes from
+ − // the HOPPING algorithm called just before calling this function.
+ − radio_freq = l1a_l1s_com.dedic_set.radio_freq;
+ −
+ − if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
+ − IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas_beacon;
+ − // we are working on a beacon freq.
+ − else
+ − IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas;
+ − // we are working on a daughter freq.
+ −
+ − #if FF_L1_IT_DSP_DTX
+ − // Skip RX DSP/RF programming part during DTX HISR
+ − if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+ − {
+ − #endif
+ −
+ − /**************************************************************************/
+ − /* TCH/T Receive... */
+ − /**************************************************************************/
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_TCHTH__DL, radio_freq);
+ − #endif
+ −
+ − /*--------------------------------------------*/
+ − /* Program DSP... */
+ − /*--------------------------------------------*/
+ −
+ − dsp_task = l1s_swap_iq_dl(radio_freq,task);
+ −
+ − // dsp pgm.
+ − l1ddsp_load_rx_task(dsp_task, 0, desc_ptr->tsc);
+ −
+ − // Set TXPWR.
+ − l1ddsp_load_txpwr(l1s.applied_txpwr, radio_freq);
+ −
+ − input_level = IL_info_ptr->input_level ;
+ −
+ − #if(RF_FAM == 61) // Locosto DCO
+ − cust_get_if_dco_ctl_algo(&dco_algo_ctl_nb, &if_ctl, (UWORD8) L1_IL_VALID,
+ − input_level ,
+ − radio_freq,if_threshold);
+ − l1ddsp_load_dco_ctl_algo_nb(dco_algo_ctl_nb);
+ − #endif
+ −
+ − /*--------------------------------------------*/
+ − /* Program TPU... */
+ − /*--------------------------------------------*/
+ − // for TCHTH we use DPAGC algorithm.
+ − #if DPAGC_MAX_FLAG
+ − agc = Cust_get_agc_from_IL(radio_freq, input_level >> 1, MAX_ID);
+ − #else
+ − agc = Cust_get_agc_from_IL(radio_freq, input_level >> 1, AV_ID);
+ − #endif
+ − lna_off = IL_info_ptr->lna_off;
+ −
+ −
+ − // Store input_level and lna_off fields used for current CTRL in order to be able
+ − // to build IL from pm in READ phase.
+ − l1a_l1s_com.Scell_used_IL = *IL_info_ptr;
+ −
+ − #if (L1_SAIC != 0)
+ − // If SAIC is enabled, call the low level SAIC control function
+ − csf_filter_choice = l1ctl_saic(l1a_l1s_com.Scell_used_IL.input_level,l1a_l1s_com.mode
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,task
+ − ,&saic_flag
+ − #endif
+ − );
+ − #endif
+ −
+ − // update the TPU with the new TOA if necessary
+ − l1ctl_update_TPU_with_toa();
+ −
+ − // Program a serving cell normal burst reading in TPU.
+ − #if (RF_FAM == 61)
+ − l1dtpu_serv_rx_nb(radio_freq,
+ − agc,
+ − lna_off,
+ − l1s.tpu_offset,
+ − l1s.tpu_offset,
+ − FALSE,INACTIVE, csf_filter_choice, if_ctl
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,saic_flag
+ − #endif /*NEW_SNR_THRESHOLD */
+ − );
+ − #endif
+ − #if (RF_FAM != 61)
+ − l1dtpu_serv_rx_nb(radio_freq,
+ − agc,
+ − lna_off,
+ − l1s.tpu_offset,
+ − l1s.tpu_offset,
+ − FALSE,INACTIVE);
+ − #endif
+ −
+ − // Increment tpu window identifier.
+ − l1s.tpu_win += (l1_config.params.rx_synth_load_split + RX_LOAD);
+ −
+ − /*--------------------------------------------*/
+ − /* Flag DSP and TPU programmation... */
+ − /*--------------------------------------------*/
+ −
+ − // Set "CTRL_RX" flag in the controle flag register.
+ − l1s.tpu_ctrl_reg |= CTRL_RX;
+ − l1s.dsp_ctrl_reg |= CTRL_RX;
+ − #if FF_L1_IT_DSP_DTX
+ − } // if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+ − #endif
+ −
+ − /**************************************************************************/
+ − /* TCH/T Transmit... */
+ − /**************************************************************************/
+ −
+ − // Any Handover Access burst to send ?
+ − // ************************************
+ −
+ − if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send != 0)
+ − // "ho_acc_to_send" is a counter of Handover Access burst still to send.
+ − // This counter is set by "l1s_dedicated_mode_manager()" in L1S when a
+ − // Handover command is received from L3 through L1A.
+ − // We must then replace the TCH UL normal burst by a RACH and decrement
+ − // this counter.
+ − {
+ − if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send != -1)
+ − l1a_l1s_com.dedic_set.aset->ho_acc_to_send --;
+ − l1s_ctrl_rach(RAHO,NO_PAR);
+ −
+ − if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send == 0)
+ − // Handover access procedure is completed.
+ − // -> send L1C_HANDOVER_FINISHED message with "cause = COMPLETED" to L1A.
+ − {
+ − l1s_send_ho_finished(HO_COMPLETE);
+ − }
+ − }
+ − else
+ − // TCH/UL is a normal burst.
+ − {
+ − UWORD8 channel_mode = l1a_l1s_com.dedic_set.aset->achan_ptr->mode;
+ − //omaps00090550 UWORD8 channel_type = desc_ptr->channel_type;
+ − UWORD8 subchannel = desc_ptr->subchannel;
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_TCHTH__UL, radio_freq);
+ − #endif
+ −
+ − #if FF_L1_IT_DSP_DTX
+ − // FACCH and IDS handled during L1S, have to be skipped during DTX HISR
+ − if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+ − {
+ − #endif
+ −
+ − /*--------------------------------------------*/
+ − /* Get DATA block if required for TCH. */
+ − /*--------------------------------------------*/
+ − // Half rate traffic channel...
+ − {
+ − // Rem: time to get data block is
+ − // Subchannel 0: FN%26 in {0, 8, 17}.
+ − // Subchannel 1: FN%26 in {1, 9, 18}.
+ − // => normalised time: FN_normalised = FN%26 - subchannel, in {0, 8, 17}.
+ − // so CTL: must occur 2 TDMAs before, on
+ − // Subchannel 0: FN%26 in {23, 6, 15}.
+ − // Subchannel 1: FN%26 in {24, 7, 16}.
+ − UWORD8 normalised_fn = l1s.next_time.t2 - subchannel; // FN%26 - subchannel
+ −
+ − if((normalised_fn == 23) || (normalised_fn == 6) || (normalised_fn == 15))
+ − // It is time to check if a FACCH/UL data block is available from DLL or
+ − // if a data block is available from the DATA interface.
+ − {
+ − T_RADIO_FRAME *tx_data = NULL;
+ −
+ − // Check if any FACCH to transmit.
+ − // Rem: when mode is "SIGNALLING ONLY" the "dll_read_dcch()" function
+ − // always give back a block of FACCH (true block or dummy one).
+ − tx_data = dll_read_dcch(channel_mode);
+ − if(tx_data != NULL)
+ − {
+ − // In DTX mode in HS, all 6 FACCH 1/2 bursts must always be transmitted.
+ − // Note: FACCH presence is checked 1 "control" before "control" of 1st burst of FACCH due to a DSP constraint
+ − // i.e. 3 bursts before FACCH interleaving boundary
+ − // So we must wait 1 control before controlling the transmission of 6 FACCH 1/2 bursts
+ − l1s.facch_bursts = 7;
+ −
+ − #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+ − RTTL1_FILL_UL_DCCH
+ − trace_info.facch_ul_count ++;
+ − #endif
+ −
+ − l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_fu, &(tx_data->A[0]));
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsptx(dltsk_trace[TCHTH].name);
+ − #endif
+ − }
+ −
+ − #if (AMR == 1)
+ − // Check if any DATA traffic info frame available.
+ − // This check is used for all full rate channels except when
+ − // this channel is in SIGNALLING ONLY mode or in Half Rate
+ − // Speech mode or in adaptative Half Rate mode.
+ − if((channel_mode != TCH_HS_MODE) &&
+ − (channel_mode != TCH_AHS_MODE) &&
+ − (channel_mode != SIG_ONLY_MODE))
+ − #else
+ − // Check if any DATA traffic info frame available.
+ − // This check is used for all full rate channels except when
+ − // this channel is in SIGNALLING ONLY mode or in Half Rate
+ − // Speech mode.
+ − if((channel_mode != TCH_HS_MODE) && (channel_mode != SIG_ONLY_MODE))
+ − #endif
+ − {
+ − UWORD8 *tx_data = NULL;
+ −
+ − tx_data = tx_tch_data();
+ − if(tx_data != NULL)
+ − {
+ − // Store the DATA/UL data block in the MCU/DSP com. according
+ − // to the "subchannel".
+ − if(subchannel == 0) l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_du_0, tx_data);
+ − else l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_du_1, tx_data);
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsptx(dltsk_trace[TCHTH].name);
+ − #endif
+ − }
+ − }
+ − }
+ − }
+ −
+ − #if FF_L1_IT_DSP_DTX
+ − // Fast DTX active only in TCH AHS
+ − if ((l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_AHS_MODE)
+ − && (l1a_l1s_com.dedic_set.aset->dtx_allowed == TRUE))
+ − {
+ − // AHS0
+ − if (desc_ptr->subchannel == 0)
+ − {
+ − // DTX interrupt request for B1 and B2 (no DTX uncertainty on B0 thanks to idle frame)
+ − if (l1s.next_time.fn_mod13 <= 7)
+ − dtx_dsp_interrupt = TRUE;
+ −
+ − // DTX uncertainty check
+ − if ((l1a_apihisr_com.dtx.fast_dtx_ready == TRUE) && // Fast DTX can be used
+ − ((l1s.next_time.fn_mod13 == 4) || (l1s.next_time.fn_mod13 == 8))) // new block boundary
+ − l1a_apihisr_com.dtx.dtx_status = DTX_AWAITED;
+ − }
+ −
+ − // AHS1
+ − else
+ − {
+ − // DTX interrupt requested for ALL blocks (idle frame does not help)
+ − dtx_dsp_interrupt = TRUE;
+ −
+ − // DTX uncertainty check
+ − if ((l1a_apihisr_com.dtx.fast_dtx_ready == TRUE) && // Fast DTX can be used
+ − ((l1s.next_time.fn_mod13 == 1) || (l1s.next_time.fn_mod13 == 5)|| (l1s.next_time.fn_mod13 == 9))) // new block boundary
+ − l1a_apihisr_com.dtx.dtx_status = DTX_AWAITED;
+ − }
+ − }
+ − else
+ − l1a_apihisr_com.dtx.dtx_status = DTX_AVAILABLE;
+ − } // if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+ −
+ − // Postpone TPU/DSP programming when DTX status not available from DSP
+ − if (l1a_apihisr_com.dtx.dtx_status != DTX_AWAITED)
+ − {
+ − BOOL tx_active =FALSE; //omaps00090550
+ − #endif
+ − /*--------------------------------------------*/
+ − /* Program DSP... */
+ − /*--------------------------------------------*/
+ −
+ − dsp_task = l1s_swap_iq_ul(radio_freq,task);
+ −
+ − l1ddsp_load_tx_task(dsp_task, 0, desc_ptr->tsc);
+ −
+ − /*--------------------------------------------*/
+ − /* Program TPU... */
+ − /*--------------------------------------------*/
+ −
+ − fn_mod_52 = l1s.actual_time.fn % 52;
+ −
+ − l1s.facch_bursts--;
+ − if (l1s.facch_bursts < 0)
+ − l1s.facch_bursts = -1;
+ − #if FF_L1_IT_DSP_DTX
+ − // Condition for TX TPU programming channel mode dependant
+ − switch (channel_mode)
+ − {
+ − case SIG_ONLY_MODE:
+ − case TCH_24H_MODE:
+ − case TCH_48H_MODE:
+ − // DTX not supported
+ − tx_active = TRUE;
+ − break;
+ −
+ − case TCH_HS_MODE:
+ − if ((l1s.dtx_ul_on == FALSE) || // No DTX
+ − ((l1s.facch_bursts >= 0) && (l1s.facch_bursts <= 5)) || // FACCH in progress
+ − ((subchannel == 0) && ((fn_mod_52 == 51) || (/*(fn_mod_52 >= 0) && omaps00090550*/(fn_mod_52 <= 5)))) || // SID HS0
+ − ((subchannel == 1) && (fn_mod_52 >= 13) && (fn_mod_52 <= 19)) // SID HS1
+ − )
+ − tx_active = TRUE;
+ − else
+ − tx_active = FALSE;
+ − break;
+ −
+ − case TCH_AHS_MODE:
+ − if (l1a_apihisr_com.dtx.tx_active) // DSP (Fast) DTX status
+ − tx_active = TRUE;
+ − else
+ − tx_active = FALSE;
+ − break;
+ − }
+ −
+ − // TPU TX burst programming
+ − if (tx_active)
+ − #else
+ −
+ − // In DTX mode, UL bursts should not be transmitted when no voice activity is detected
+ − // we must not call TPU scenario if dtx_on == TRUE in HS (See Technical Memo)
+ − // However, in DTX mode, several bursts must always be transmitted (See ETSI 05.08, 8.3)
+ − if ( (channel_mode != TCH_HS_MODE) ||
+ − (l1s.dtx_ul_on == FALSE) ||
+ − ( (l1s.facch_bursts >= 0) && (l1s.facch_bursts <= 5) ) ||
+ − ( (subchannel == 0) && ((fn_mod_52 == 51) || ((fn_mod_52 >= 0) && (fn_mod_52 <= 5))) ) ||
+ − ( (subchannel == 1) && (fn_mod_52 >= 13) && (fn_mod_52 <= 19) ))
+ − #endif
+ − {
+ − l1dtpu_serv_tx_nb(radio_freq, l1a_l1s_com.dedic_set.aset->timing_advance, l1s.tpu_offset, l1s.applied_txpwr,INACTIVE);
+ − }
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − RTTL1_FILL_UL_NB(task, l1a_l1s_com.dedic_set.aset->timing_advance, l1s.applied_txpwr)
+ − #endif
+ −
+ − #if FF_L1_IT_DSP_DTX
+ − } // if (l1a_apihisr_com.dtx.dtx_status != DTX_AWAITED)
+ − #endif
+ − } // TCH/UL is a normal burst.
+ −
+ −
+ − #if FF_L1_IT_DSP_DTX
+ − // Postpone TPU/DSP programming when DTX status not available from DSP
+ − if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+ − {
+ − #endif
+ −
+ − /*----------------------------------------------*/
+ − /* Common for Dedicated mode: DSP parameters... */
+ − /*----------------------------------------------*/
+ − #if (AMR == 1)
+ − #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+ − desc_ptr->channel_type,
+ − desc_ptr->subchannel,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+ − l1a_l1s_com.dedic_set.sync_tch,
+ − l1a_l1s_com.dedic_set.sync_amr,
+ − l1a_l1s_com.dedic_set.reset_sacch,
+ − #if !FF_L1_IT_DSP_DTX
+ − l1a_l1s_com.dedic_set.vocoder_on);
+ − #else
+ − l1a_l1s_com.dedic_set.vocoder_on,
+ − dtx_dsp_interrupt);
+ − #endif
+ − #else
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+ − desc_ptr->channel_type,
+ − desc_ptr->subchannel,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+ − l1a_l1s_com.dedic_set.sync_tch,
+ − #if !FF_L1_IT_DSP_DTX
+ − l1a_l1s_com.dedic_set.sync_amr);
+ − #else
+ − l1a_l1s_com.dedic_set.sync_amr,
+ − dtx_dsp_interrupt);
+ − #endif
+ − #endif
+ −
+ − // Clear "sync_amr" flag to maintain normal TCH process.
+ − l1a_l1s_com.dedic_set.sync_amr = FALSE;
+ − #else
+ − #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+ − desc_ptr->channel_type,
+ − desc_ptr->subchannel,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+ − l1a_l1s_com.dedic_set.sync_tch,
+ − l1a_l1s_com.dedic_set.reset_sacch,
+ − #if !FF_L1_IT_DSP_DTX
+ − l1a_l1s_com.dedic_set.vocoder_on);
+ − #else
+ − l1a_l1s_com.dedic_set.vocoder_on,
+ − dtx_dsp_interrupt);
+ − #endif
+ − #else
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+ − desc_ptr->channel_type,
+ − desc_ptr->subchannel,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+ − #if !FF_L1_IT_DSP_DTX
+ − l1a_l1s_com.dedic_set.sync_tch);
+ − #else
+ − l1a_l1s_com.dedic_set.sync_tch,
+ − dtx_dsp_interrupt);
+ − #endif
+ − #endif
+ − #endif
+ −
+ − // reset the FACCH header of the API buffer on the control following an ABORT to avoid decoding unwanted FACCH
+ − if (l1a_l1s_com.dedic_set.reset_facch == TRUE)
+ − {
+ − // Reset A_FD header.
+ − // B_FIRE1 =1, B_FIRE0 =0 , BLUD =0
+ − l1s_dsp_com.dsp_ndb_ptr->a_fd[0] = (1<<B_FIRE1);
+ − l1s_dsp_com.dsp_ndb_ptr->a_fd[2] = 0xffff;
+ − }
+ −
+ − // Clear "sync_tch" and "reset_sacch" flag to maintain normal TCH process.
+ − l1a_l1s_com.dedic_set.sync_tch = FALSE;
+ − l1a_l1s_com.dedic_set.reset_facch = FALSE;
+ − #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+ − l1a_l1s_com.dedic_set.reset_sacch = FALSE;
+ − #endif
+ −
+ − // Set tpu window identifier for Power meas.
+ − l1s.tpu_win = (3 * BP_SPLIT) + l1_config.params.tx_nb_load_split + l1_config.params.rx_synth_load_split;
+ −
+ − /*--------------------------------------------*/
+ − /* Flag DSP and TPU programmation... */
+ − /*--------------------------------------------*/
+ −
+ − // Set "CTRL_TX" flag in the controle flag register.
+ − l1s.tpu_ctrl_reg |= CTRL_TX;
+ − l1s.dsp_ctrl_reg |= CTRL_TX;
+ − #if FF_L1_IT_DSP_DTX
+ − } //if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+ − #endif
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_tchtf() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* dedicated mode TCH task: TCHTF. This function is the */
+ − /* control function for reading the DL burst and sending */
+ − /* the UL burst. The UL burst can be a Normal Burst in */
+ − /* normal case or an Access Burst when starting a */
+ − /* Handover procedure. Both Half rate and Full rate TCH */
+ − /* channel are handled. The DSP and the TPU are */
+ − /* programmed for both the DL and UL bursts. The timing */
+ − /* advance is taken into account for positionning the UL */
+ − /* burst. */
+ − /* */
+ − /* This function accesses the L1/DLL and L1/DATA */
+ − /* interface ("dll_read_dcch()", "tx_tch_data()" */
+ − /* functions respectively) and passes then the returned */
+ − /* data blocks to the DSP. */
+ − /* */
+ − /* Here is a summary of the execution: */
+ − /* */
+ − /* - Traces and debug. */
+ − /* - Catch channel description and ARFCN. */
+ − /* - TCH/T Receive... */
+ − /* - Program DSP for RX. */
+ − /* - Program TPU for RX. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* - TCH/T Transmit... */
+ − /* - If Any Handover Access burst to send */
+ − /* - Call "l1s_ctrl_rach()". */
+ − /* - Else */
+ − /* - Get DATA block if required for TCH. */
+ − /* - Program DSP for TX. */
+ − /* - Program TPU for TX. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* - Common for DL/UL: DSP parameters. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* TCHTF, Traffic Channel TCH Full rate. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.dedic_set" */
+ − /* Dedicated channel parameter structure. */
+ − /* .radio_freq, ARFCN value set by the Hopping algo. */
+ − /* .aset, active dedicated parameter set. */
+ − /* */
+ − /* "l1a_l1s_com.Scell_info" */
+ − /* Serving cell information structure. */
+ − /* .bsic, BSIC of the serving cell. It is used here */
+ − /* to pass the training sequence number (part */
+ − /* of BSIC) to the DSP. */
+ − /* */
+ − /* "l1s.afc" */
+ − /* current AFC value to be applied for the given task. */
+ − /* */
+ − /* "l1s.tpu_offset" */
+ − /* value for the TPU SYNCHRO and OFFSET registers */
+ − /* for current serving cell setting. */
+ − /* */
+ − /* "l1s.applied_txpwr" */
+ − /* Applied transmit power. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.tpu_win" */
+ − /* each frame is composed with a maximum of 3 */
+ − /* working/TPU windows (typically RX/TX/PW). This is */
+ − /* a counter used to count the number of windows */
+ − /* used. */
+ − /* -> set to TDMA_WIN3. */
+ − /* */
+ − /* "l1s.tpu_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/TPU com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* -> set CTRL_TX bit in the register. */
+ − /* */
+ − /* "l1s.dsp_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/DSP com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* -> set CTRL_TX bit in the register. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_ctrl_tchtf(UWORD8 task, UWORD8 param2)
+ − {
+ − UWORD16 radio_freq=0;
+ − T_CHANNEL_DESCRIPTION *desc_ptr;
+ − UWORD8 lna_off;
+ − WORD8 agc;
+ − T_INPUT_LEVEL *IL_info_ptr;
+ − UWORD32 dsp_task;
+ − UWORD32 fn_mod_104;
+ − #if (RF_FAM == 61)
+ − UWORD16 dco_algo_ctl_nb;
+ − UWORD8 if_ctl =0 ; //omaps00090550
+ − UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+ − // By default we choose the hardware filter
+ − UWORD8 csf_filter_choice = L1_SAIC_HARDWARE_FILTER;
+ − #endif
+ − #if FF_L1_IT_DSP_DTX
+ − BOOL dtx_dsp_interrupt = FALSE;
+ − #endif
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − UWORD8 saic_flag;
+ − #endif
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsp_tpu(dltsk_trace[TCHTF].name);
+ − #endif
+ −
+ − l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+ −
+ − // Catch channel description and ARFCN.
+ − // *************************************
+ −
+ − // Catch the active channel description used along the routine.
+ − // It contains:
+ − // "channel_type", {TCH_F, TCH_H, SDCCH_4, SDCCH_8}.
+ − // "subchannel", {0, 1}. 0 is the default value for TCH_F.
+ − desc_ptr = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr;
+ −
+ − // Get ARFCN to be used for current control. This ARFCN comes from
+ − // the HOPPING algorithm called just before calling this function.
+ − radio_freq = l1a_l1s_com.dedic_set.radio_freq;
+ −
+ − if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
+ − IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas_beacon;
+ − // we are working on a beacon freq.
+ − else
+ − IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas;
+ − // we are working on a daughter freq.
+ −
+ − #if FF_L1_IT_DSP_DTX
+ − // Skip RX DSP/RF programming part during DTX HISR
+ − if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+ − {
+ − #endif
+ −
+ − /**************************************************************************/
+ − /* TCH/T Receive... */
+ − /**************************************************************************/
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_TCHTF__DL, radio_freq);
+ − #endif
+ −
+ − /*--------------------------------------------*/
+ − /* Program DSP... */
+ − /*--------------------------------------------*/
+ − // dsp pgm.
+ −
+ − dsp_task = l1s_swap_iq_dl(radio_freq,task);
+ −
+ − l1ddsp_load_rx_task(dsp_task, 0, desc_ptr->tsc);
+ −
+ − #if(RF_FAM == 61) // Locosto DCO
+ − cust_get_if_dco_ctl_algo(&dco_algo_ctl_nb, &if_ctl, (UWORD8) L1_IL_VALID,
+ − IL_info_ptr->input_level ,
+ − radio_freq,if_threshold);
+ − l1ddsp_load_dco_ctl_algo_nb(dco_algo_ctl_nb);
+ − #endif
+ −
+ − #if TESTMODE
+ − // if Normal Mode or
+ − // if TestMode DL+UL
+ − // NOTE: UL only true if DL is true in TCHTF!
+ − if ( !l1_config.TestMode ||
+ − (l1_config.TestMode && (l1_config.tmode.rf_params.down_up & TMODE_UPLINK)))
+ − #endif
+ − {
+ − // Set TXPWR.
+ − l1ddsp_load_txpwr(l1s.applied_txpwr, radio_freq);
+ − }
+ −
+ − /*--------------------------------------------*/
+ − /* Program TPU... */
+ − /*--------------------------------------------*/
+ −
+ − // for TCHTF we use DPAGC algorithm.
+ − #if DPAGC_MAX_FLAG
+ − agc = Cust_get_agc_from_IL(radio_freq, IL_info_ptr->input_level >> 1, MAX_ID);
+ − #else
+ − agc = Cust_get_agc_from_IL(radio_freq, IL_info_ptr->input_level >> 1, AV_ID);
+ − #endif
+ − lna_off = IL_info_ptr->lna_off;
+ −
+ −
+ − // Store input_level and lna_off fields used for current CTRL in order to be able
+ − // to build IL from pm in READ phase.
+ − l1a_l1s_com.Scell_used_IL = *IL_info_ptr;
+ −
+ − #if (L1_SAIC != 0)
+ − // If SAIC is enabled, call the low level SAIC control function
+ − csf_filter_choice = l1ctl_saic(l1a_l1s_com.Scell_used_IL.input_level,l1a_l1s_com.mode
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,task
+ − ,&saic_flag
+ − #endif
+ − );
+ − #endif
+ −
+ − #if TESTMODE
+ − // Continuous mode: Rx TPU programmation only in NO_CONTINUOUS or START_RX_CONTINUOUS mode.
+ − if ((!l1_config.TestMode) ||
+ − (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS) ||
+ − (l1_config.tmode.rf_params.tmode_continuous == TM_START_RX_CONTINUOUS))
+ − #endif
+ − {
+ − // update the TPU with the new TOA if necessary
+ − l1ctl_update_TPU_with_toa();
+ −
+ − // Program a serving cell normal burst reading in TPU.
+ − l1dtpu_serv_rx_nb(radio_freq,
+ − agc,
+ − lna_off,
+ − l1s.tpu_offset,
+ − l1s.tpu_offset,
+ − FALSE,INACTIVE
+ − #if (RF_FAM == 61)
+ − ,csf_filter_choice
+ − ,if_ctl
+ − #endif
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,saic_flag
+ − #endif /*NEW_SNR_THRESHOLD*/
+ − );
+ − }
+ −
+ − // Increment tpu window identifier.
+ − l1s.tpu_win += (l1_config.params.rx_synth_load_split + RX_LOAD);
+ −
+ − /*--------------------------------------------*/
+ − /* Flag DSP and TPU programmation... */
+ − /*--------------------------------------------*/
+ −
+ − // Set "CTRL_RX" flag in the controle flag register.
+ −
+ − #if TESTMODE
+ − // Continuous mode: swap TPU page for Rx only in NO_CONTINUOUS or START_RX_CONTINUOUS mode.
+ − if ((!l1_config.TestMode) ||
+ − (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS) ||
+ − (l1_config.tmode.rf_params.tmode_continuous == TM_START_RX_CONTINUOUS))
+ − #endif
+ − {
+ − l1s.tpu_ctrl_reg |= CTRL_RX;
+ − }
+ − l1s.dsp_ctrl_reg |= CTRL_RX;
+ − #if FF_L1_IT_DSP_DTX
+ − } // if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+ − #endif
+ −
+ − /**************************************************************************/
+ − /* TCH/T Transmit... */
+ − /**************************************************************************/
+ −
+ − // Any Handover Access burst to send ?
+ − // ************************************
+ −
+ − if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send != 0)
+ − // "ho_acc_to_send" is a counter of Handover Access burst still to send.
+ − // This counter is set by "l1s_dedicated_mode_manager()" in L1S when a
+ − // Handover command is received from L3 through L1A.
+ − // We must then replace the TCH UL normal burst by a RACH and decrement
+ − // this counter.
+ − {
+ − if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send != -1)
+ − l1a_l1s_com.dedic_set.aset->ho_acc_to_send --;
+ − l1s_ctrl_rach(RAHO,NO_PAR);
+ −
+ − if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send == 0)
+ − // Handover access procedure is completed.
+ − // -> send L1C_HANDOVER_FINISHED message with "cause = COMPLETED" to L1A.
+ − {
+ − l1s_send_ho_finished(HO_COMPLETE);
+ − }
+ − }
+ − else
+ − // TCH/UL is a normal burst.
+ − {
+ − UWORD8 channel_mode = l1a_l1s_com.dedic_set.aset->achan_ptr->mode;
+ − //OMAPS00090550 UWORD8 channel_type = desc_ptr->channel_type;
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_TCHTF__UL, radio_freq);
+ − #endif
+ −
+ − #if FF_L1_IT_DSP_DTX
+ − // FACCH and IDS handled during L1S, have to be skipped during DTX HISR
+ − if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+ − {
+ − #endif
+ − /*--------------------------------------------*/
+ − /* Get DATA block if required for TCH. */
+ − /*--------------------------------------------*/
+ − // Full rate traffic channel...
+ − {
+ − UWORD8 fn_report_mod13_mod4 = (l1s.next_time.fn_in_report % 13) % 4;
+ −
+ − if(fn_report_mod13_mod4 == 3)
+ − // It is time to check if a FACCH/UL data block is available from DLL or
+ − // if a data block is available from the DATA interface.
+ − {
+ − T_RADIO_FRAME *tx_data = NULL;
+ −
+ − // Check if any FACCH to transmit.
+ − // Rem: when mode is "SIGNALLING ONLY" the "dll_read_dcch()" function
+ − // always gives back a block of FACCH (true block or dummy one).
+ − // In ETM test mode, the protocol stack is not active and hence we do not require any FACCH data from L23
+ − // But this change is applicable only when ETM scripts are run with PS-builds. In case of L1-SA,
+ − // dll_read_dcch() is called which is just a stub function (It just returns a NULL ptr for L1 SA)
+ − /* FreeCalypso: this logic is not present in TCS211 */
+ − #if 0
+ − #if TESTMODE
+ − #if (OP_L1_STANDALONE == 0)
+ − if(!l1_config.TestMode)
+ − #endif // (OP_L1_STANDALONE == 0)
+ − #endif // TESTMODE
+ − #endif
+ − {
+ − tx_data = dll_read_dcch(channel_mode);
+ − }
+ −
+ − if(tx_data != NULL)
+ − {
+ − // In DTX mode in FR and EFR, all 8 FACCH 1/2 bursts must always be transmitted.
+ − // Note: FACCH presence is checked 1 "control" before "control" of 1st burst of FACCH due to a DSP constraint
+ − // i.e. 2 bursts before FACCH interleaving boundary
+ − //So we must wait 1 burst before controlling the transmission of 8 FACCH 1/2 bursts
+ − l1s.facch_bursts = 9;
+ −
+ − #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+ − RTTL1_FILL_UL_DCCH
+ − trace_info.facch_ul_count ++;
+ − #endif
+ −
+ − // Store the FACCH/UL data block in the MCU/DSP com.
+ − #if TRACE_TYPE==3
+ − if (l1_stats.type == PLAY_UL)
+ − {
+ − // load A_DU_1 in PLAY Uplink mode.
+ − l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_du_1, &(tx_data->A[0]));
+ −
+ −
+ − if (channel_mode == TCH_EFR_MODE)
+ − {
+ − WORD32 bit5word14, bit2word14, bit12word15, bit15word15;
+ −
+ − // clear CRC bits and repetition bits
+ − l1s_dsp_com.dsp_ndb_ptr->a_du_1[7] &= 0x807f;
+ − l1s_dsp_com.dsp_ndb_ptr->a_du_1[14] &= 0xfc24;
+ − l1s_dsp_com.dsp_ndb_ptr->a_du_1[15] &= 0x93ff;
+ − l1s_dsp_com.dsp_ndb_ptr->a_du_1[19] &= 0xff00;
+ −
+ − // read repetition bits
+ − bit5word14 = (l1s_dsp_com.dsp_ndb_ptr->a_du_1[14] >> 5)& 0x1;
+ − bit2word14 = (l1s_dsp_com.dsp_ndb_ptr->a_du_1[14] >> 2)& 0x1;
+ − bit12word15 = (l1s_dsp_com.dsp_ndb_ptr->a_du_1[15] >> 12) & 0x1;
+ − bit15word15 = (l1s_dsp_com.dsp_ndb_ptr->a_du_1[15] >> 15)& 0x1;
+ −
+ − // copy repetition bits
+ − l1s_dsp_com.dsp_ndb_ptr->a_du_1[14] |=
+ − (bit5word14 << 4 | bit5word14 << 3 |
+ − bit2word14 | bit2word14 << 1);
+ −
+ − l1s_dsp_com.dsp_ndb_ptr->a_du_1[15] |=
+ − (bit15word15 << 13 | bit12word15 << 14 |
+ − bit12word15 << 10 | bit15word15 << 11);
+ − }
+ − else
+ − {
+ − l1s_dsp_com.dsp_ndb_ptr->a_du_1[14] &= 0xfc3f;
+ − l1s_dsp_com.dsp_ndb_ptr->a_du_1[19] &= 0xff00;
+ − }
+ −
+ − // set PLAY Uplink bit .......
+ − l1s_dsp_com.dsp_ndb_ptr->d_tch_mode |= (1 << B_PLAY_UL);
+ − }
+ − else
+ − l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_fu, &(tx_data->A[0]));
+ − #else
+ − l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_fu, &(tx_data->A[0]));
+ − #endif
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsptx(dltsk_trace[TCHTF].name);
+ − #endif
+ − }
+ −
+ − #if (AMR == 1)
+ − // Check if any DATA traffic info frame available.
+ − // This check is used for all full rate channels except when
+ − // this channel is in SIGNALLING ONLY mode or in Full Rate
+ − // Speech mode or adaptative full rate mode.
+ − if((channel_mode != TCH_FS_MODE) &&
+ − (channel_mode != SIG_ONLY_MODE) &&
+ − (channel_mode != TCH_EFR_MODE) &&
+ − (channel_mode != TCH_AFS_MODE))
+ − #else
+ − // Check if any DATA traffic info frame available.
+ − // This check is used for all full rate channels except when
+ − // this channel is in SIGNALLING ONLY mode or in Full Rate
+ − // Speech mode.
+ − if((channel_mode != TCH_FS_MODE) &&
+ − (channel_mode != SIG_ONLY_MODE) &&
+ − (channel_mode != TCH_EFR_MODE))
+ − #endif
+ − {
+ − #if IDS
+ − {
+ − UWORD8 fn_report_mod26;
+ − API *data_ul;
+ −
+ − data_ul = l1s_dsp_com.dsp_ndb_ptr->a_du_0;
+ − fn_report_mod26 = l1s.next_time.fn_in_report%26;
+ −
+ − // Set flag for UL/DL block information: for TCH/F48 mode only
+ − if((channel_mode == TCH_48F_MODE) && ((fn_report_mod26 == 7) || (fn_report_mod26 == 16)
+ − || (fn_report_mod26 == 24)))
+ − l1s_dsp_com.dsp_ndb_ptr->d_ra_act |= (3 << B_F48BLK);
+ − else
+ − l1s_dsp_com.dsp_ndb_ptr->d_ra_act &= ~(3 << B_F48BLK);
+ − dll_data_ul(l1s_dsp_com.dsp_ndb_ptr->a_data_buf_ul, &l1s_dsp_com.dsp_ndb_ptr->d_ra_conf,
+ − &l1s_dsp_com.dsp_ndb_ptr->d_ra_act, &l1s_dsp_com.dsp_ndb_ptr->d_ra_test,
+ − &l1s_dsp_com.dsp_ndb_ptr->d_ra_statu, &l1s_dsp_com.dsp_ndb_ptr->d_fax);
+ −
+ − // Fill a_du_0 data block Header.
+ − // Note: a_du_0 header is fill when dummy block is filled as well when data block
+ − // is filled (buffer a_data_buf_ul
+ − data_ul[0] = (1 << B_BLUD); // 1st word: Set B_BLU bit.
+ − data_ul[1] = 0; // 2nd word: cleared.
+ − data_ul[2] = 0; // 3rd word: cleared.
+ −
+ − }
+ − #else
+ − {
+ − UWORD8 *tx_data = NULL;
+ −
+ − tx_data = tx_tch_data();
+ − if(tx_data != NULL)
+ − {
+ − // Store the DATA/UL data block in the MCU/DSP com.
+ − #if TRACE_TYPE==3
+ − if (l1_stats.type == PLAY_UL)
+ − {
+ − // load A_DU_1 in PLAY Uplink mode.
+ − l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_du_1, tx_data);
+ − if (channel_mode == TCH_48F_MODE)
+ − l1s_dsp_com.dsp_ndb_ptr->a_du_1[10] &= 0x00ff;
+ − if (channel_mode == TCH_24F_MODE)
+ − l1s_dsp_com.dsp_ndb_ptr->a_du_1[7] &= 0x00ff;
+ − // set PLAY Uplink bit .......
+ − l1s_dsp_com.dsp_ndb_ptr->d_tch_mode |= (1 << B_PLAY_UL);
+ − }
+ − else
+ − l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_du_0, tx_data);
+ − #else
+ − l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_du_0, tx_data);
+ − #endif
+ − }
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsptx(dltsk_trace[TCHTF].name);
+ − #endif
+ − }
+ − #endif
+ − }
+ − }
+ − }
+ −
+ − #if FF_L1_IT_DSP_DTX
+ − // Fast DTX active only in TCH AFS, for TDMA3 from speech block = 0, 1 [MOD 3]
+ − if ((l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_AFS_MODE)
+ − && (l1a_l1s_com.dedic_set.aset->dtx_allowed == TRUE))
+ − {
+ − // DTX interrupt request for B1 and B2 (no DTX uncertainty on B0 thanks to idle frame)
+ − if (l1s.next_time.fn_mod13 <= 7)
+ − dtx_dsp_interrupt = TRUE;
+ −
+ − // DTX uncertainty check
+ − if ((l1a_apihisr_com.dtx.fast_dtx_ready == TRUE) && // Fast DTX can be used
+ − ((l1s.next_time.fn_mod13 == 4) || (l1s.next_time.fn_mod13 == 8))) // new block boundary
+ − l1a_apihisr_com.dtx.dtx_status = DTX_AWAITED;
+ − }
+ − else
+ − l1a_apihisr_com.dtx.dtx_status = DTX_AVAILABLE;
+ − } // if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+ −
+ − // Postpone TPU/DSP programming when DTX status not available from DSP
+ − if (l1a_apihisr_com.dtx.dtx_status != DTX_AWAITED)
+ − {
+ − BOOL tx_active =FALSE; //omaps00090550
+ − #endif
+ − #if TESTMODE
+ − // if Normal Mode or
+ − // if TestMode and UL+DL
+ − // NOTE: UL only true if DL is true in TCHTF!
+ − if ( !l1_config.TestMode ||
+ − (l1_config.TestMode && (l1_config.tmode.rf_params.down_up & TMODE_UPLINK)))
+ − #endif
+ − {
+ − /*--------------------------------------------*/
+ − /* Program DSP... */
+ − /*--------------------------------------------*/
+ −
+ − dsp_task = l1s_swap_iq_ul(radio_freq,task);
+ −
+ − l1ddsp_load_tx_task(dsp_task, 0, desc_ptr->tsc);
+ −
+ − /*--------------------------------------------*/
+ − /* Program TPU... */
+ − /*--------------------------------------------*/
+ −
+ − fn_mod_104 = l1s.actual_time.fn % 104;
+ −
+ − #if TESTMODE
+ − if ((!l1_config.TestMode) ||
+ − (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS) ||
+ − (l1_config.tmode.rf_params.tmode_continuous == TM_START_TX_CONTINUOUS))
+ − #endif
+ − {
+ − l1s.facch_bursts--;
+ − if (l1s.facch_bursts < 0)
+ − l1s.facch_bursts = -1;
+ −
+ − #if FF_L1_IT_DSP_DTX
+ − // Condition for TX TPU programming channel mode dependant
+ − switch (channel_mode)
+ − {
+ − case SIG_ONLY_MODE:
+ − case TCH_24F_MODE:
+ − case TCH_48F_MODE:
+ − case TCH_96_MODE:
+ − case TCH_144_MODE:
+ − // DTX not supported
+ − tx_active = TRUE;
+ − break;
+ −
+ − case TCH_FS_MODE:
+ − case TCH_EFR_MODE:
+ − if ((l1s.dtx_ul_on == FALSE) || // No DTX
+ − ((l1s.facch_bursts >= 0) && (l1s.facch_bursts <= 7)) || // FACCH in progress
+ − ((fn_mod_104 >= 51) && (fn_mod_104 <= 58)) // SID
+ − )
+ − tx_active = TRUE;
+ − else
+ − tx_active = FALSE;
+ − break;
+ −
+ − case TCH_AFS_MODE:
+ − if (l1a_apihisr_com.dtx.tx_active) // DSP (Fast) DTX status
+ − tx_active = TRUE;
+ − else
+ − tx_active = FALSE;
+ − break;
+ − }
+ −
+ − // TPU TX burst programming
+ − if (tx_active)
+ − #else
+ − // In DTX mode, UL bursts should not be transmitted when no voice activity is detected
+ − // we must not call TPU scenario if dtx_on == TRUE in EFR and FR (See Technical Memo)
+ − // However, in DTX mode, bursts 52 to 59 (modulo 104) must always be transmitted
+ − // FACCH must also be transmitted but we must wait 1 bursts before transmitting 8 1/2 bursts
+ − if ( ((channel_mode != TCH_FS_MODE) && (channel_mode != TCH_EFR_MODE)) ||
+ − (l1s.dtx_ul_on == FALSE) ||
+ − ( (l1s.facch_bursts >= 0) && (l1s.facch_bursts <= 7) ) ||
+ − ((fn_mod_104 >= 51) && (fn_mod_104 <= 58)) )
+ − #endif
+ − {
+ − l1dtpu_serv_tx_nb(radio_freq, l1a_l1s_com.dedic_set.aset->timing_advance, l1s.tpu_offset, l1s.applied_txpwr,INACTIVE);
+ − }
+ − }
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − RTTL1_FILL_UL_NB(task, l1a_l1s_com.dedic_set.aset->timing_advance, l1s.applied_txpwr)
+ − #endif
+ −
+ − }
+ − #if FF_L1_IT_DSP_DTX
+ − } // if (l1a_apihisr_com.dtx.dtx_status != DTX_AWAITED)
+ − #endif
+ − } // TCH/UL is a normal burst.
+ − #if FF_L1_IT_DSP_DTX
+ − // Postpone TPU/DSP programming when DTX status not available from DSP
+ − if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+ − {
+ − #endif
+ −
+ − /*----------------------------------------------*/
+ − /* Common for Dedicated mode: DSP parameters... */
+ − /*----------------------------------------------*/
+ − #if (AMR == 1)
+ − #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+ − desc_ptr->channel_type,
+ − 0,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+ − l1a_l1s_com.dedic_set.sync_tch,
+ − l1a_l1s_com.dedic_set.sync_amr,
+ − l1a_l1s_com.dedic_set.reset_sacch,
+ − #if !FF_L1_IT_DSP_DTX
+ − l1a_l1s_com.dedic_set.vocoder_on);
+ − #else
+ − l1a_l1s_com.dedic_set.vocoder_on,
+ − dtx_dsp_interrupt);
+ − #endif
+ − #else
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+ − desc_ptr->channel_type,
+ − 0,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+ − l1a_l1s_com.dedic_set.sync_tch,
+ − #if !FF_L1_IT_DSP_DTX
+ − l1a_l1s_com.dedic_set.sync_amr);
+ − #else
+ − l1a_l1s_com.dedic_set.sync_amr,
+ − dtx_dsp_interrupt);
+ − #endif
+ − #endif
+ −
+ − // Clear "sync_amr" flag to maintain normal TCH process.
+ − l1a_l1s_com.dedic_set.sync_amr = FALSE;
+ − #else
+ − #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+ − desc_ptr->channel_type,
+ − 0,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+ − l1a_l1s_com.dedic_set.sync_tch,
+ − l1a_l1s_com.dedic_set.reset_sacch,
+ − #if !FF_L1_IT_DSP_DTX
+ − l1a_l1s_com.dedic_set.vocoder_on);
+ − #else
+ − l1a_l1s_com.dedic_set.vocoder_on,
+ − dtx_dsp_interrupt);
+ − #endif
+ − #else
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+ − desc_ptr->channel_type,
+ − 0,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+ − #if !FF_L1_IT_DSP_DTX
+ − l1a_l1s_com.dedic_set.sync_tch);
+ − #else
+ − l1a_l1s_com.dedic_set.sync_tch,
+ − dtx_dsp_interrupt);
+ − #endif
+ − #endif
+ − #endif
+ −
+ − // reset the FACCH header of the API buffer on the control following an ABORT to avoid decoding unwanted FACCH
+ − if (l1a_l1s_com.dedic_set.reset_facch == TRUE)
+ − {
+ − // Reset A_FD header.
+ − // B_FIRE1 =1, B_FIRE0 =0 , BLUD =0
+ − l1s_dsp_com.dsp_ndb_ptr->a_fd[0] = (1<<B_FIRE1);
+ − l1s_dsp_com.dsp_ndb_ptr->a_fd[2] = 0xffff;
+ − }
+ −
+ − // Clear "sync_tch" and "reset_sacch" flag to maintain normal TCH process.
+ − l1a_l1s_com.dedic_set.sync_tch = FALSE;
+ − l1a_l1s_com.dedic_set.reset_facch = FALSE;
+ − #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+ − l1a_l1s_com.dedic_set.reset_sacch = FALSE;
+ − #endif
+ −
+ − // Set tpu window identifier for Power meas or FS/SB search.
+ − l1s.tpu_win = (3 * BP_SPLIT) + l1_config.params.tx_nb_load_split + l1_config.params.rx_synth_load_split;
+ −
+ − /*--------------------------------------------*/
+ − /* Flag DSP and TPU programmation... */
+ − /*--------------------------------------------*/
+ −
+ − #if TESTMODE
+ − // if Normal Mode or
+ − // if TestMode and UL+DL
+ − // NOTE: UL only true if DL is true in TCHTF!
+ − if ( !l1_config.TestMode ||
+ − ( l1_config.TestMode && (l1_config.tmode.rf_params.down_up & TMODE_UPLINK)))
+ − #endif
+ − {
+ − #if TESTMODE
+ − // Continuous mode: swap TPU page for Tx in NO_CONTINUOUS or START_TX_CONTINUOUS mode.
+ − if ((!l1_config.TestMode) ||
+ − (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS) ||
+ − (l1_config.tmode.rf_params.tmode_continuous == TM_START_TX_CONTINUOUS))
+ − #endif
+ − {
+ − l1s.tpu_ctrl_reg |= CTRL_TX;
+ − }
+ − l1s.dsp_ctrl_reg |= CTRL_TX;
+ − }
+ −
+ − #if TESTMODE
+ − // Continuous mode: if end of control of START_RX/TX: go to CONTINUOUS state
+ − if (l1_config.TestMode && (l1_config.tmode.rf_params.tmode_continuous != TM_NO_CONTINUOUS))
+ − l1_config.tmode.rf_params.tmode_continuous = TM_CONTINUOUS;
+ − #endif
+ − #if FF_L1_IT_DSP_DTX
+ − } //if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+ − #endif
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_ctrl_tcha() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* dedicated mode TCH task: TCHA. This function is the */
+ − /* control function for reading the DL burst and sending */
+ − /* the UL burst on the Slow Associated Channel (SACCH) */
+ − /* associated with the traffic channel. The UL burst can */
+ − /* be a Normal Burst in normal case or an Access Burst */
+ − /* when starting a Handover procedure. Both Half rate */
+ − /* and Full rate TCH channel are handled. The DSP and */
+ − /* the TPU are programmed for both the DL and UL bursts. */
+ − /* The timing advance is taken into account for */
+ − /* positionning the UL burst. */
+ − /* */
+ − /* This function accesses the L1/DLL interface */
+ − /* ("dll_read_sacch()" function) and passes then the */
+ − /* returned data blocks to the DSP after having set the */
+ − /* L1 header part of the block. */
+ − /* */
+ − /* Here is a summary of the execution: */
+ − /* */
+ − /* - Traces and debug. */
+ − /* - Catch channel description and ARFCN. */
+ − /* - TCH/SACCH Receive... */
+ − /* - Program DSP for RX. */
+ − /* - Program TPU for RX. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* - TCH/SACCH Transmit... */
+ − /* - If Any Handover Access burst to send */
+ − /* - Call "l1s_ctrl_rach()". */
+ − /* - Else */
+ − /* - Get DATA block from DLL if required. */
+ − /* - Program DSP for TX. */
+ − /* - Program TPU for TX. */
+ − /* - Flag DSP and TPU programmation. */
+ − /* - Common for DL/UL: DSP parameters. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* TCHA, Associated channel task when dedicated/TCH. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.dedic_set" */
+ − /* Dedicated channel parameter structure. */
+ − /* .radio_freq, ARFCN value set by the Hopping algo. */
+ − /* .aset, active dedicated parameter set. */
+ − /* */
+ − /* "l1a_l1s_com.Scell_info" */
+ − /* Serving cell information structure. */
+ − /* .bsic, BSIC of the serving cell. It is used here */
+ − /* to pass the training sequence number (part */
+ − /* of BSIC) to the DSP. */
+ − /* */
+ − /* "l1s.afc" */
+ − /* current AFC value to be applied for the given task. */
+ − /* */
+ − /* "l1s.tpu_offset" */
+ − /* value for the TPU SYNCHRO and OFFSET registers */
+ − /* for current serving cell setting. */
+ − /* */
+ − /* "l1s.applied_txpwr" */
+ − /* Applied transmit power. */
+ − /* */
+ − /* "l1s.reported_txpwr" */
+ − /* Transmit power to report in the L1 header of the */
+ − /* SACCH data block. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.tpu_win" */
+ − /* each frame is composed with a maximum of 3 */
+ − /* working/TPU windows (typically RX/TX/PW). This is */
+ − /* a counter used to count the number of windows */
+ − /* used. */
+ − /* -> set to TDMA_WIN3. */
+ − /* */
+ − /* "l1s.tpu_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/TPU com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* -> set CTRL_TX bit in the register. */
+ − /* */
+ − /* "l1s.dsp_ctrl_reg" */
+ − /* bit register used to know at the end of L1S if */
+ − /* something has been programmed on the MCU/DSP com. */
+ − /* This is used mainly to swap then the com. page at */
+ − /* the end of a control frame. */
+ − /* -> set CTRL_RX bit in the register. */
+ − /* -> set CTRL_TX bit in the register. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_ctrl_tcha(UWORD8 task, UWORD8 param2)
+ − {
+ − UWORD16 radio_freq=0;
+ − T_CHANNEL_DESCRIPTION *desc_ptr;
+ − UWORD8 lna_off =0;//omaps00090550
+ − WORD8 agc =0; //omaps00090550
+ − T_INPUT_LEVEL *IL_info_ptr;
+ − UWORD32 dsp_task;
+ − UWORD8 adc_active_ul = INACTIVE;
+ − UWORD8 adc_active_dl = INACTIVE;
+ − #if (RF_FAM == 61)
+ − UWORD16 dco_algo_ctl_nb = 0;
+ − UWORD8 if_ctl = 0;
+ − UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+ − // By default we choose the hardware filter
+ − UWORD8 csf_filter_choice = L1_SAIC_HARDWARE_FILTER;
+ − #endif
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − UWORD8 saic_flag=0;
+ − #endif /*NEW_SNR_THRESHOLD */
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsp_tpu(dltsk_trace[TCHA].name);
+ − #endif
+ −
+ − l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+ −
+ − // Catch channel description and ARFCN.
+ − // *************************************
+ −
+ − // Catch the active channel description used along the routine.
+ − // It contains:
+ − // "channel_type", {TCH_F, TCH_H, SDCCH_4, SDCCH_8}.
+ − // "subchannel", {0, 1}. 0 is the default value for TCH_F.
+ − desc_ptr = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr;
+ −
+ − // Get ARFCN to be used for current control.
+ − radio_freq = l1a_l1s_com.dedic_set.radio_freq;
+ −
+ − if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
+ − IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas_beacon;
+ − // we are working on a beacon freq.
+ − else
+ − IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas;
+ − // we are working on a daughter freq.
+ −
+ − /**************************************************************************/
+ − /* SACCH Receive... */
+ − /**************************************************************************/
+ −
+ − // ADC measurement
+ − // ***************
+ −
+ − // check if during the SACCH burst an ADC measurement must be performed
+ − if (l1a_l1s_com.adc_mode & ADC_NEXT_TRAFFIC_DL) // perform ADC only one time
+ − {
+ − adc_active_dl = ACTIVE;
+ − l1a_l1s_com.adc_mode &= ADC_MASK_RESET_TRAFFIC; // reset in order to have only one ADC measurement in Traffic
+ − }
+ − else
+ − if (l1a_l1s_com.adc_mode & ADC_EACH_TRAFFIC_DL) // perform ADC on each period bloc
+ − if (l1s.next_time.fn_in_report == 12) //periodic with each 1st SACCH burst
+ − if ((++l1a_l1s_com.adc_cpt)>=l1a_l1s_com.adc_traffic_period) // wait for the period
+ − {
+ − adc_active_dl = ACTIVE;
+ − l1a_l1s_com.adc_cpt = 0;
+ − }
+ −
+ − #if TESTMODE
+ − // if Normal Mode or
+ − // if TestMode and DL-only or DL+UL
+ − if ( !l1_config.TestMode ||
+ − (l1_config.TestMode && (l1_config.tmode.rf_params.down_up & TMODE_DOWNLINK)))
+ − #endif
+ − {
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_TCHA___DL, radio_freq);
+ − #endif
+ −
+ − /*--------------------------------------------*/
+ − /* Program DSP... */
+ − /*--------------------------------------------*/
+ − // dsp pgm.
+ −
+ − dsp_task = l1s_swap_iq_dl(radio_freq,task);
+ − l1ddsp_load_rx_task(dsp_task, 0, desc_ptr->tsc);
+ −
+ − #if(RF_FAM == 61) // Locosto DCO
+ − cust_get_if_dco_ctl_algo(&dco_algo_ctl_nb, &if_ctl, (UWORD8) L1_IL_VALID ,
+ − IL_info_ptr->input_level ,
+ − radio_freq,if_threshold);
+ − l1ddsp_load_dco_ctl_algo_nb(dco_algo_ctl_nb);
+ − #endif
+ −
+ − /*--------------------------------------------*/
+ − /* Program TPU... */
+ − /*--------------------------------------------*/
+ − // for TCHA we use DPAGC algorithm.
+ − #if DPAGC_MAX_FLAG
+ − agc = Cust_get_agc_from_IL(radio_freq, IL_info_ptr->input_level >> 1, MAX_ID);
+ − #else
+ − agc = Cust_get_agc_from_IL(radio_freq, IL_info_ptr->input_level >> 1, AV_ID);
+ − #endif
+ − lna_off = IL_info_ptr->lna_off;
+ −
+ −
+ −
+ − // Store input_level and lna_off fields used for current CTRL in order to be able
+ − // to build IL from pm in READ phase.
+ − l1a_l1s_com.Scell_used_IL = *IL_info_ptr;
+ −
+ − #if (L1_SAIC != 0)
+ − // If SAIC is enabled, call the low level SAIC control function
+ − csf_filter_choice = l1ctl_saic(l1a_l1s_com.Scell_used_IL.input_level,l1a_l1s_com.mode
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,task
+ − ,&saic_flag
+ − #endif
+ − );
+ − #endif
+ −
+ − #if TESTMODE
+ − // Continuous mode: Rx TPU programmation only in NO_CONTINUOUS or START_RX_CONTINUOUS mode.
+ − if ((!l1_config.TestMode) ||
+ − (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS) ||
+ − (l1_config.tmode.rf_params.tmode_continuous == TM_START_RX_CONTINUOUS))
+ − #endif
+ − {
+ − // update the TPU with the new TOA if necessary
+ − l1ctl_update_TPU_with_toa();
+ −
+ − // Program a serving cell normal burst reading in TPU.
+ − l1dtpu_serv_rx_nb(radio_freq,
+ − agc,
+ − lna_off,
+ − l1s.tpu_offset,
+ − l1s.tpu_offset,
+ − FALSE,adc_active_dl
+ − #if (RF_FAM == 61)
+ − ,csf_filter_choice
+ − ,if_ctl
+ − #endif
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,saic_flag
+ − #endif /* NEW_SNR_THRESHOLD */
+ − );
+ − }
+ −
+ − // Increment tpu window identifier.
+ − l1s.tpu_win += (l1_config.params.rx_synth_load_split + RX_LOAD);
+ −
+ − // Set "CTRL_RX" flag in the control flag register.
+ − #if TESTMODE
+ − // Continuous mode: swap TPU page for Rx only in NO_CONTINUOUS or START_RX_CONTINUOUS mode.
+ − if ((!l1_config.TestMode) ||
+ − (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS) ||
+ − (l1_config.tmode.rf_params.tmode_continuous == TM_START_RX_CONTINUOUS))
+ − #endif
+ − {
+ − l1s.tpu_ctrl_reg |= CTRL_RX;
+ − }
+ − l1s.dsp_ctrl_reg |= CTRL_RX;
+ −
+ − }
+ −
+ − /**************************************************************************/
+ − /* TCH/T Transmit... */
+ − /**************************************************************************/
+ −
+ − // Any Handover Access burst to send ? --> TXPWR management
+ − // ************************************
+ −
+ − if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send != 0)
+ − // "ho_acc_to_send" is a counter of Handover Access burst still to send.
+ − // This counter is set by "l1s_dedicated_mode_manager()" in L1S when a
+ − // Handover command is received from L3 through L1A.
+ − // When Handover access is in progress, nothing but RACH can be transmitted.
+ − // RACH is not allowed on SACCH therefore TX is avoided by setting
+ − // the txpwr to NO_TXPWR !!!
+ − {
+ − #if 0 /* LoCosto code */
+ − // NOTE: The spec says RACH bursts on SACCH UL is optional. hence it should not be counted
+ − // Refer spec 04.08
+ − l1s_ctrl_rach(RAHO,NO_PAR);
+ − #else /* TCS211 reconstruction, code taken from TSM30 */
+ − // Set TXPWR.
+ − l1ddsp_load_txpwr(NO_TXPWR, radio_freq);
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − RTTL1_FILL_UL_NB(task, l1a_l1s_com.dedic_set.aset->timing_advance, NO_TXPWR)
+ − #endif
+ − #endif
+ − }
+ − else
+ − // TCH/UL is a normal burst.
+ − // TX power must be the normal one
+ − {
+ − // Set TXPWR.
+ − l1ddsp_load_txpwr(l1s.applied_txpwr, radio_freq);
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − RTTL1_FILL_UL_NB(task, l1a_l1s_com.dedic_set.aset->timing_advance, l1s.applied_txpwr)
+ − #endif
+ −
+ − // ADC measurement
+ − // ***************
+ −
+ − // check if during the SACCH burst an ADC measurement must be performed
+ − if (l1a_l1s_com.adc_mode & ADC_NEXT_TRAFFIC_UL) // perform ADC only one time
+ − {
+ − adc_active_ul = ACTIVE;
+ − l1a_l1s_com.adc_mode &= ADC_MASK_RESET_TRAFFIC; // reset in order to have only one ADC measurement in Traffic
+ − }
+ − else
+ − if (l1a_l1s_com.adc_mode & ADC_EACH_TRAFFIC_UL) // perform ADC on each period bloc
+ − if (l1s.next_time.fn_in_report == 12) //periodic with each 1st SACCH burst
+ − if ((++l1a_l1s_com.adc_cpt)>=l1a_l1s_com.adc_traffic_period) // wait for the period
+ − {
+ − adc_active_ul = ACTIVE;
+ − l1a_l1s_com.adc_cpt = 0;
+ − }
+ −
+ − #if 1 /* FreeCalypso TCS211 reconstruction */
+ − } // End of "TCH/UL is a normal burst"
+ − #endif
+ −
+ − // In any case (normal TX or no TX due to Handover Access process)
+ − // the full TCHA task must be controled for TPU and DSP.
+ − {
+ − T_RADIO_FRAME *tx_data = NULL;
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_CTRL_TCHA___UL, radio_freq);
+ − #endif
+ −
+ − /*--------------------------------------------*/
+ − /* Get DATA block if required for SACCH. */
+ − /*--------------------------------------------*/
+ − if(l1s.next_time.fn_in_report == 12)
+ − // It is time to get a SACCH data block from DLL.
+ − // Call "dll_read_sacch()" to perform "PH_DATA_REQ" and pass
+ − // the data block to the DSP..
+ − {
+ − #if ((FF_REPEATED_SACCH) && ( TESTMODE))
+ − if(l1_config.repeat_sacch_enable != REPEATED_SACCH_ENABLE)
+ − {
+ − l1s.repeated_sacch.sro = 0;
+ − l1s.repeated_sacch.buffer_empty = TRUE;
+ − }
+ − #endif /* #if ((FF_REPEATED_SACCH) && ( TESTMODE)) */
+ − #if FF_REPEATED_SACCH
+ − /* Get data from PS if only no repetition order is required (1st condition) */
+ − /* or no repetition candidate exists (2nd condition) */
+ − if((l1s.repeated_sacch.sro == 0) || (l1s.repeated_sacch.buffer_empty == TRUE))
+ − #endif /* FF_REPEATED_SACCH */
+ − {
+ − tx_data = dll_read_sacch(SIG_ONLY_MODE);
+ − if(tx_data != NULL)
+ − {
+ − // Set L1 Header...
+ − tx_data->A[0] = l1s.reported_txpwr;
+ − tx_data->A[1] = l1a_l1s_com.dedic_set.aset->timing_advance;
+ −
+ − #if FF_REPEATED_SACCH
+ − /* Include the SACCH Repetition Request (SRR) in the L1 Header */
+ − tx_data->A[0] |= (l1s.repeated_sacch.srr <<6);
+ − #endif /* FF_REPEATED_SACCH */
+ − // Put data block in MCU/DSP com.
+ − l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_cu, &(tx_data->A[0]));
+ − #if (FF_REPEATED_SACCH == 1 )
+ − if(((tx_data->A[2]&0x1C) >> 2) == SAPI_0) /* Store the block data in case of a retransmission order */
+ − {
+ − l1s_store_sacch_buffer( &(l1s.repeated_sacch), &(tx_data->A[0]));
+ − /* Stores the buffer and turns of the buffer_empty flag as false */
+ − }
+ − else
+ − {
+ − /* the SACCH repetition block occurrence will always come as a consecutive pair */
+ − /* To handle DL UL | DL UL | DL UL */
+ − /* - 0 | SRO 3 | - new data should be asked from PS old 0 cannot be repeated */
+ − l1s.repeated_sacch.buffer_empty=TRUE;
+ − }
+ − #endif /* FF_REPEATED_SACCH */
+ − } /* if(tx_data != NULL) */
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dsptx(dltsk_trace[TCHA].name);
+ − #endif
+ − }/* if((l1s.repeated_sacch.sro == 0) || (l1s.repeated_sacch.buffer_empty == TRUE))*/
+ − #if FF_REPEATED_SACCH
+ − else if ((l1s.repeated_sacch.sro == 1) && (l1s.repeated_sacch.buffer_empty == FALSE))
+ − {
+ − /* Put data block in MCU/DSP com. */
+ − l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_cu, l1s.repeated_sacch.buffer );
+ − l1s.repeated_sacch.buffer_empty = TRUE; /* Set that the buffer is now empty (only one repetition) */
+ − } /* end else repetition */
+ − #endif /* FF_REPEATED_SACCH */
+ − // check to be removed
+ − }
+ −
+ − /*--------------------------------------------*/
+ − /* Program DSP... */
+ − /*--------------------------------------------*/
+ − #if TESTMODE
+ − // UL-only...
+ − // Use SPI to write to Omega uplink buffer, do NOT use DSP
+ − if (l1_config.TestMode && l1_config.tmode.rf_params.down_up == TMODE_UPLINK)
+ − {
+ − #if (CODE_VERSION != SIMULATION)
+ − // For Calyso+ & Before...
+ − #if (RF_FAM == 12)
+ − ABB_Write_Register_on_page(PAGE0, AUXAPC, Cust_get_pwr_data(l1s.applied_txpwr, radio_freq
+ − #if(REL99 && FF_PRF)
+ − ,1
+ − #endif
+ − ));
+ − l1tm_fill_burst(l1_config.tmode.tx_params.burst_data, &TM_ul_data[0]);
+ − ABB_Write_Uplink_Data(&TM_ul_data[0]);
+ − #endif
+ −
+ − //For UppCosto, Tx Data Write is via PLD to DRP & Ramp is via the ABB Driver
+ − #if (RF_FAM == 60)
+ − ABB_Write_Register_on_page(PAGE0, AUXAPC, Cust_get_pwr_data(l1s.applied_txpwr, radio_freq
+ − #if(REL99 && FF_PRF)
+ − ,1
+ − #endif
+ − ));
+ − l1tm_fill_burst(l1_config.tmode.tx_params.burst_data, &TM_ul_data[0]);
+ − PLD_Write_Uplink_Data(&TM_ul_data[0]);
+ − #endif
+ −
+ − #if (RF_FAM == 61)
+ − // For DRP we use the DSP to write the TX Power via a new variable apclev in API
+ − // A new variable is required in API as DSP copies the tx_power_ctl (which is
+ − // normally used to pass the APCLEV value to DSP) to APCLEV ONLY when there is a
+ − // burst to be transmitted
+ − l1ddsp_apc_load_apclev(Cust_get_pwr_data(l1s.applied_txpwr, radio_freq
+ − #if(REL99 && FF_PRF)
+ − ,1
+ − #endif
+ − ));
+ − l1tm_fill_burst(l1_config.tmode.tx_params.burst_data, &TM_ul_data[0]);
+ − DRP_Write_Uplink_Data(&TM_ul_data[0]);
+ − #endif
+ −
+ − #endif
+ − }
+ − // Use DSP...
+ − // if Normal Mode or
+ − // if TestMode and DL+UL
+ − else if ( !l1_config.TestMode ||
+ − (l1_config.TestMode && l1_config.tmode.rf_params.down_up == (TMODE_DOWNLINK|TMODE_UPLINK)))
+ − {
+ − dsp_task = l1s_swap_iq_ul(radio_freq,task);
+ −
+ − l1ddsp_load_tx_task(dsp_task, 0, desc_ptr->tsc);
+ − }
+ − #else
+ − dsp_task = l1s_swap_iq_ul(radio_freq,task);
+ −
+ − l1ddsp_load_tx_task(dsp_task, 0, desc_ptr->tsc);
+ − #endif
+ −
+ − /*--------------------------------------------*/
+ − /* Program TPU... */
+ − /*--------------------------------------------*/
+ − #if TESTMODE
+ − // if Normal Mode or
+ − // if TestMode and UL-only or DL+UL
+ − if ( !l1_config.TestMode ||
+ − (l1_config.TestMode && (l1_config.tmode.rf_params.down_up & TMODE_UPLINK) &&
+ − (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS ||
+ − l1_config.tmode.rf_params.tmode_continuous == TM_START_TX_CONTINUOUS)))
+ − #endif
+ − {
+ − l1dtpu_serv_tx_nb(radio_freq, l1a_l1s_com.dedic_set.aset->timing_advance, l1s.tpu_offset, l1s.applied_txpwr, adc_active_ul);
+ − }
+ − }
+ −
+ − #if 0 /* FreeCalypso TCS211 reconstruction */
+ − } // End of "TCH/UL is a normal burst"
+ − #endif
+ −
+ − /*----------------------------------------------*/
+ − /* Common for Dedicated mode: DSP parameters... */
+ − /*----------------------------------------------*/
+ −
+ − #if (AMR == 1)
+ − #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+ − desc_ptr->channel_type,
+ − desc_ptr->subchannel,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+ − l1a_l1s_com.dedic_set.sync_tch,
+ − l1a_l1s_com.dedic_set.sync_amr,
+ − l1a_l1s_com.dedic_set.reset_sacch,
+ − #if !FF_L1_IT_DSP_DTX
+ − l1a_l1s_com.dedic_set.vocoder_on);
+ − #else
+ − l1a_l1s_com.dedic_set.vocoder_on,
+ − 0);
+ − #endif
+ − #else // FF_L1_TCH_VOCODER_CONTROL
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+ − desc_ptr->channel_type,
+ − desc_ptr->subchannel,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+ − l1a_l1s_com.dedic_set.sync_tch,
+ − #if !FF_L1_IT_DSP_DTX
+ − l1a_l1s_com.dedic_set.sync_amr);
+ − #else
+ − l1a_l1s_com.dedic_set.sync_amr,
+ − 0);
+ − #endif
+ − #endif // FF_L1_TCH_VOCODER_CONTROL
+ −
+ − l1a_l1s_com.dedic_set.sync_amr = FALSE;
+ −
+ − #else // AMR
+ − #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+ − desc_ptr->channel_type,
+ − desc_ptr->subchannel,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+ − l1a_l1s_com.dedic_set.sync_tch,
+ − l1a_l1s_com.dedic_set.reset_sacch,
+ − #if !FF_L1_IT_DSP_DTX
+ − l1a_l1s_com.dedic_set.vocoder_on);
+ − #else
+ − l1a_l1s_com.dedic_set.vocoder_on,
+ − 0);
+ − #endif
+ − #else
+ − l1ddsp_load_tch_param(&(l1s.next_time),
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+ − desc_ptr->channel_type,
+ − desc_ptr->subchannel,
+ − l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+ − #if !FF_L1_IT_DSP_DTX
+ − l1a_l1s_com.dedic_set.sync_tch);
+ − #else
+ − l1a_l1s_com.dedic_set.sync_tch,
+ − 0);
+ − #endif
+ − #endif
+ − #endif // AMR
+ −
+ − // Clear "sync_tch" flag to maintain normal TCH process.
+ − l1a_l1s_com.dedic_set.sync_tch = FALSE;
+ − #if (FF_L1_TCH_VOCODER_CONTROL)
+ − l1a_l1s_com.dedic_set.reset_sacch = FALSE;
+ − #endif
+ −
+ − #if 0 /* FreeCalypso TCS211 reconstruction */
+ − if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send == 0)
+ − {
+ − #endif
+ − // Set tpu window identifier for Power meas or FS/SB search.
+ − l1s.tpu_win = (3 * BP_SPLIT) + l1_config.params.tx_nb_load_split + l1_config.params.rx_synth_load_split;
+ −
+ − /*--------------------------------------------*/
+ − /* Flag DSP and TPU programmation... */
+ − /*--------------------------------------------*/
+ − #if TESTMODE
+ − // if Normal Mode or
+ − // if TestMode and UL-only or DL+UL
+ − if ( !l1_config.TestMode ||
+ − (l1_config.TestMode && (l1_config.tmode.rf_params.down_up & TMODE_UPLINK)))
+ − #endif
+ − {
+ − #if TESTMODE
+ − // Continuous mode: swap TPU page for Tx in NO_CONTINUOUS or START_TX_CONTINUOUS mode.
+ − if ((!l1_config.TestMode) ||
+ − (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS) ||
+ − (l1_config.tmode.rf_params.tmode_continuous == TM_START_TX_CONTINUOUS))
+ − #endif
+ − {
+ − l1s.tpu_ctrl_reg |= CTRL_TX;
+ − }
+ − l1s.dsp_ctrl_reg |= CTRL_TX;
+ − }
+ −
+ − #if TESTMODE
+ − // Continuous mode: if end of control of START_RX/TX: go to CONTINUOUS state
+ − if (l1_config.TestMode && (l1_config.tmode.rf_params.tmode_continuous != TM_NO_CONTINUOUS))
+ − l1_config.tmode.rf_params.tmode_continuous = TM_CONTINUOUS;
+ − #endif
+ −
+ − #if 0 /* FreeCalypso TCS211 reconstruction */
+ − }
+ − #endif
+ − }
+ −
+ − #if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_hopping_algo() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* dedicated mode tasks: DDL, DUL, ADL, AUL, TCHTH/F and */
+ − /* TCHA. This function performs the Hopping Sequence */
+ − /* generation. It computes the ARFCN to use on the next */
+ − /* frame. When the channel does not hop, it returns */
+ − /* the fixe ARFCN provided in the channel description. */
+ − /* */
+ − /* If the channel is hopping and the ARFCN result is the */
+ − /* BEACON frequency, an indication flag is set to warn */
+ − /* the DSP ("b_bcch_freq_ind"). */
+ − /* */
+ − /* (see GSM05.02 $6.2.3) */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.dedic_set.aset" */
+ − /* Active set of Dedicated channel parameters. */
+ − /* */
+ − /* "l1s.l1s.next_time" */
+ − /* frame number and derived numbers for next frame. */
+ − /* */
+ − /* Returned parameter in globals: */
+ − /* ------------------------------ */
+ − /* */
+ − /* "l1a_l1s_com.dedic_set.radio_freq" */
+ − /* ARFCN to be used on the next frame. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_hopping_algo(UWORD8 task, UWORD8 param2)
+ − {
+ − UWORD8 mai;
+ − T_CHN_SEL *chan_sel;
+ − T_MOBILE_ALLOCATION *alist_ptr;
+ −
+ − UWORD16 *ma;
+ − UWORD8 n;
+ − UWORD8 hsn;
+ − UWORD8 maio;
+ − UWORD16 *radio_freq_ptr;
+ − UWORD16 *beacon_channel_ptr=&l1a_l1s_com.Scell_info.radio_freq; // beacon channel of the serving cell
+ − T_TIME_INFO *time_ptr;
+ − T_TIME_INFO next_neighbor_time;
+ −
+ −
+ − switch(task)
+ − {
+ −
+ − #if L1_GPRS
+ − case PTCCH:
+ − {
+ − chan_sel = &(l1pa_l1ps_com.transfer.aset->freq_param.chan_sel);
+ − alist_ptr = &(l1pa_l1ps_com.transfer.aset->freq_param.freq_list);
+ − radio_freq_ptr = &l1pa_l1ps_com.transfer.ptcch.radio_freq;
+ − time_ptr = &l1s.next_time;
+ − }
+ − break;
+ −
+ − case PDTCH:
+ − case SINGLE:
+ − // For PDTCH, set pointers to the PACKET parameter structures.
+ − {
+ − chan_sel = &(l1pa_l1ps_com.transfer.aset->freq_param.chan_sel);
+ − alist_ptr = &(l1pa_l1ps_com.transfer.aset->freq_param.freq_list);
+ − radio_freq_ptr = &l1a_l1s_com.dedic_set.radio_freq;
+ − time_ptr = &l1s.next_time;
+ − }
+ − break;
+ −
+ − case PALLC:
+ − case PNP:
+ − case PEP:
+ − {
+ − chan_sel = &l1pa_l1ps_com.pccch.packet_chn_desc.chan_sel;
+ − alist_ptr = &l1pa_l1ps_com.pccch.frequency_list;
+ − radio_freq_ptr = &l1pa_l1ps_com.p_idle_param.radio_freq;
+ − time_ptr = &l1s.next_time;
+ − }
+ − break;
+ −
+ − case POLL:
+ − {
+ − // Load adequat freq. list according to the current mode:
+ − // SINGLE (i.e. 2 phase access) else Packet Access or Packet Idle
+ − if(l1a_l1s_com.l1s_en_task[SINGLE] == TASK_ENABLED)
+ − {
+ − chan_sel = &(l1pa_l1ps_com.transfer.aset->freq_param.chan_sel);
+ − alist_ptr = &(l1pa_l1ps_com.transfer.aset->freq_param.freq_list);
+ − radio_freq_ptr = &l1a_l1s_com.dedic_set.radio_freq;
+ − }
+ − else
+ − {
+ − chan_sel = &l1pa_l1ps_com.pccch.packet_chn_desc.chan_sel;
+ − alist_ptr = &l1pa_l1ps_com.pccch.frequency_list;
+ − radio_freq_ptr = &l1pa_l1ps_com.p_idle_param.radio_freq;
+ − }
+ − time_ptr = &l1s.next_time;
+ − }
+ − break;
+ −
+ − case PBCCHS:
+ − {
+ − chan_sel = &l1pa_l1ps_com.pbcchs.packet_chn_desc.chan_sel;
+ − alist_ptr = &l1pa_l1ps_com.pbcchs.frequency_list;
+ − radio_freq_ptr = &l1pa_l1ps_com.p_idle_param.radio_freq;
+ −
+ − // If PBCCHS controlled one frame in advance --> correct Frame Number when PBCCH block is read
+ − if (l1pa_l1ps_com.pbcchs.control_offset)
+ − time_ptr = &l1s.next_plus_time;
+ − else
+ − time_ptr = &l1s.next_time;
+ − }
+ − break;
+ −
+ − case PBCCHN_IDLE:
+ − case PBCCHN_TRAN:
+ − {
+ − WORD32 next_neighbor_time_fn;
+ −
+ − chan_sel = &l1pa_l1ps_com.pbcchn.packet_chn_desc.chan_sel;
+ − alist_ptr = &l1pa_l1ps_com.pbcchn.frequency_list;
+ − radio_freq_ptr = &l1pa_l1ps_com.p_idle_param.radio_freq;
+ − beacon_channel_ptr = &l1pa_l1ps_com.pbcchn.bcch_carrier;
+ − time_ptr = &next_neighbor_time;
+ −
+ − // To review (is there any better solution?)...........
+ − next_neighbor_time_fn = l1s.next_time.fn + l1pa_l1ps_com.pbcchn.fn_offset;
+ −
+ − #if 0 /* correct code (corrected by TI for LoCosto) */
+ − if (next_neighbor_time_fn > ((WORD32)MAX_FN))//OMAPS00090550
+ − #else /* wrong code to match TCS211 disassembly */
+ − if (next_neighbor_time_fn > MAX_FN)
+ − #endif
+ − next_neighbor_time.fn = (UWORD32) (next_neighbor_time_fn - MAX_FN);
+ − else if (next_neighbor_time_fn < 0)
+ − next_neighbor_time.fn = (UWORD32) (next_neighbor_time_fn + MAX_FN);
+ − else
+ − next_neighbor_time.fn = (UWORD32) (next_neighbor_time_fn);
+ −
+ − next_neighbor_time.t1 = next_neighbor_time.fn / (26L*51L); // T1 = FN div 26*51
+ − next_neighbor_time.t2 = next_neighbor_time.fn % 26; // T2 = FN % 26.
+ − next_neighbor_time.t3 = next_neighbor_time.fn % 51; // T3 = FN % 51.
+ − }
+ − break;
+ −
+ − case ITMEAS:
+ − {
+ − // Packet transfer mode
+ − if (l1a_l1s_com.l1s_en_task[PDTCH] == TASK_ENABLED)
+ − {
+ − // We use the active TBF frequency parameters
+ − chan_sel = &(l1pa_l1ps_com.transfer.aset->freq_param.chan_sel);
+ − alist_ptr = &(l1pa_l1ps_com.transfer.aset->freq_param.freq_list);
+ − }
+ −
+ − // Packet idle mode
+ − else
+ − {
+ − // We use the frequency parameters given in the MPHP_INT_MEAS_REQ message
+ − chan_sel = &(l1pa_l1ps_com.itmeas.packet_intm_freq_param.chan_sel);
+ − alist_ptr = &(l1pa_l1ps_com.itmeas.packet_intm_freq_param.freq_list);
+ − }
+ −
+ − radio_freq_ptr = &l1pa_l1ps_com.itmeas.radio_freq;
+ − time_ptr = &l1s.next_plus_time;
+ − }
+ − break;
+ −
+ − #endif
+ −
+ − case SMSCB:
+ − // For SMSCB, set pointers to the SMSCB parameter structures.
+ − {
+ − chan_sel = &l1a_l1s_com.cbch_desc.chan_sel;
+ − alist_ptr = &l1a_l1s_com.cbch_freq_list;
+ − radio_freq_ptr = &l1a_l1s_com.dedic_set.radio_freq;
+ −
+ − // If SMSCB is controlled one frame in advance --> correct Frame Number when SMSCB block is read
+ − if (l1a_l1s_com.pre_scheduled_cbch)
+ − time_ptr = &l1s.next_plus_time;
+ − else
+ − time_ptr = &l1s.next_time;
+ − }
+ − break;
+ −
+ − default:
+ − // For SDCCH/TCH, set pointers to the active channel description.
+ − {
+ − chan_sel = &(l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->chan_sel);
+ − alist_ptr = l1a_l1s_com.dedic_set.aset->ma.alist_ptr;
+ − radio_freq_ptr = &l1a_l1s_com.dedic_set.radio_freq;
+ − time_ptr = &l1s.next_time;
+ − }
+ − } // End of switch(task)
+ −
+ − // Set local variables.
+ − ma = &(alist_ptr->rf_chan_no.A[0]);
+ − n = alist_ptr->rf_chan_cnt;
+ − hsn = chan_sel->rf_channel.hopping_rf.hsn;
+ − maio = chan_sel->rf_channel.hopping_rf.maio;
+ −
+ − if(chan_sel->h == FALSE)
+ − // Single RF channel, NOT HOPPING.
+ − {
+ − *radio_freq_ptr = chan_sel->rf_channel.single_rf.radio_freq;
+ − }
+ −
+ − else
+ − // Hopping channel...
+ − {
+ − /**************************************************/
+ − /* Perform the HOPPING algorithm. */
+ − /**************************************************/
+ − if(hsn == 0)
+ − // Cyclic hopping...
+ − {
+ − mai = (time_ptr->fn + maio) % n;
+ − }
+ − else
+ − {
+ − UWORD8 i = 0;
+ − UWORD8 m;
+ − UWORD8 mp;
+ − UWORD8 nbin;
+ − UWORD8 tp;
+ − UWORD8 s;
+ − UWORD8 t1r = (UWORD8)(time_ptr->t1 % 64);
+ −
+ − while(i<=6)
+ − {
+ − if((n >> i) > 0) nbin = i;
+ − i++;
+ − }
+ − nbin++;
+ −
+ − m = time_ptr->t2 + RNTABLE[(hsn ^ t1r) + time_ptr->t3];
+ − mp = m % (1L << nbin);
+ − tp = time_ptr->t3 % (1L << nbin);
+ −
+ − if(mp < n) s = mp;
+ − else s = (mp + tp) % n;
+ −
+ − mai = (s + maio) % n;
+ − }
+ −
+ − *radio_freq_ptr = ma[mai];
+ − }
+ −
+ − if(*radio_freq_ptr == *beacon_channel_ptr)
+ − // If ARFCN is the BEACON...
+ − {
+ − // Set "b_bcch_freq_ind" to TRUE.
+ − l1s_dsp_com.dsp_db_w_ptr->d_ctrl_system |= (1 << B_BCCH_FREQ_IND);
+ −
+ − }
+ − }
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+ − #endif // MOVE_IN_INTERNAL_RAM
+ −
+ − //===============================================================================================//
+ −
+ − #if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM !=0)) // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM enabled
+ − //#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_START // KEEP IN EXTERNAL MEM otherwise
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_read_dummy() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* task: ABORT. Since this task just aborts any ongoing */
+ − /* DSP task, there is no result returned by the DSP to */
+ − /* the MCU when this abort is completed, but the MCU/DSP */
+ − /* com. read page must be switched properly. This the */
+ − /* only reason why we have created this function. */
+ − /* */
+ − /* Modified parameter in globals: */
+ − /* ------------------------------ */
+ − /* */
+ − /* "l1s_dsp_com.dsp_r_page_used" */
+ − /* Flag used by the function which closes L1S */
+ − /* execution ("l1s_end_manager()") to know if the */
+ − /* MCU/DSP read page must be switched. */
+ − /* -> Set to 1. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_read_dummy(UWORD8 task, UWORD8 param2)
+ − {
+ − l1_check_com_mismatch(task);
+ −
+ − #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+ − trace_fct(CST_L1S_READ_DUMMY ,(UWORD32)(-1));//OMAPS00090550
+ − #endif
+ −
+ − // task is completed, make it INACTIVE (only in case of TCHD).
+ − if(task == TCHD)
+ − l1s.task_status[task].current_status = INACTIVE;
+ −
+ − #if FF_L1_IT_DSP_DTX
+ − // Fast DTX status update
+ − if(task == TCHD)
+ − {
+ − UWORD8 subchannel = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->subchannel;
+ −
+ − // Currently used for TCH-AHS only
+ − if (((subchannel == 0) && (l1s.actual_time.fn_mod13_mod4 == 0)) || // FN%13 = 4, 8 and 12 for TCH/H0 (no Read on FN%13=0)
+ − ((subchannel == 1) && (l1s.actual_time.fn_mod13_mod4 == 1))) // FN%13 = 1, 5 and 9 for TCH/H1
+ − {
+ − // Latch TX activity status if DTX allowed
+ − if ((l1a_l1s_com.dedic_set.aset->dtx_allowed == FALSE) || // No DTX allowed
+ − (l1s_dsp_com.dsp_ndb_ptr->d_fast_dtx_enc_data ) || // DTX allowed but not used
+ − (l1a_apihisr_com.dtx.fast_dtx_ready == FALSE)) // Fast DTX status is invalid
+ − l1a_apihisr_com.dtx.tx_active = TRUE;
+ − else
+ − l1a_apihisr_com.dtx.tx_active = FALSE;
+ − }
+ − }
+ − #endif
+ − // Set flag used to change the read page at the end of "l1_synch".
+ − l1s_dsp_com.dsp_r_page_used = TRUE;
+ − }
+ −
+ − //#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END
+ − #endif
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_read_msagc() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* tasks: BCCHN,FBNEW,SB1,SB2,SBCONF. This function is */
+ − /* the reading result function used for reading a power */
+ − /* measurement result used then to refreshing the AGC */
+ − /* for those tasks. Here is a summary of the execution: */
+ − /* */
+ − /* - If SEMAPHORE(task) is low. */
+ − /* - Get the cell information structure. */
+ − /* - Traces and debug. */
+ − /* - Read receive level result from MCU/DSP interface.*/
+ − /* - Flag the use of the MCU/DSP dual page read */
+ − /* interface. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* BCCHN, BCCH Neighbor reading task. */
+ − /* FBNEW, Frequency Burst detection task in Idle mode. */
+ − /* SB1, Synchro Burst reading task in Idle mode. */
+ − /* SB2, Synchro Burst detection task in Idle mode. */
+ − /* SBCONF, Synchro Burst confirmation task in Idle */
+ − /* mode. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.Ncell_info.bcch" */
+ − /* "l1a_l1s_com.Ncell_info.acquis" */
+ − /* "l1a_l1s_com.Ncell_info.acquis" */
+ − /* "l1a_l1s_com.Ncell_info.conf" */
+ − /* cell information structure used for BCCHN,FBNEW, */
+ − /* SB1/SB2,SBCONF respectively. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s_dsp_com.dsp_r_page_used" */
+ − /* Flag used by the function which closes L1S */
+ − /* execution ("l1s_end_manager()") to know if the */
+ − /* MCU/DSP read page must be switched. */
+ − /* -> Set to 1. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_read_msagc(UWORD8 task, UWORD8 param2)
+ − {
+ − BOOL en_task;
+ − BOOL task_param;
+ − UWORD8 pm_level[2];
+ − #if (L1_FF_MULTIBAND == 1)
+ − UWORD16 operative_radio_freq;
+ − #endif
+ −
+ −
+ − // Get "enable" task flag and "synchro semaphore" for current task.
+ − en_task = l1a_l1s_com.l1s_en_task[task];
+ − task_param = l1a_l1s_com.task_param[task];
+ −
+ − if((en_task) && !(task_param))
+ − // Check the task semaphore and the task enable bit. The reading
+ − // task body is executed only when the task semaphore is 0 and the
+ − // task is still enabled.
+ − // The semaphore can be set to 1 whenever L1A makes some changes
+ − // to the task parameters. The task can be disabled by L1A.
+ − {
+ − T_NCELL_SINGLE *cell_info_ptr = NULL;
+ − #if (L1_GPRS)
+ − T_NCELL_SINGLE pbcchn_cell_info;
+ − #endif
+ − #if ((REL99 == 1) && (FF_BHO == 1))
+ − T_NCELL_SINGLE bho_cell_info;
+ − #endif
+ −
+ − // Get the cell information structure.
+ − // ************************************
+ −
+ − switch(task)
+ − {
+ − case BCCHN_TOP: cell_info_ptr = &l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_top ]; break;
+ − case BCCHN: cell_info_ptr = &l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_norm ]; break;
+ − case FBNEW: cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id]; break;
+ − case SB2: cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sb_id]; break;
+ − case SBCONF: cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sbconf_id]; break;
+ − #if ((REL99 == 1) && (FF_BHO == 1))
+ − case FBSB:
+ − {
+ − cell_info_ptr = &bho_cell_info;
+ − bho_cell_info.radio_freq = l1a_l1s_com.nsync_fbsb.radio_freq;
+ − bho_cell_info.fn_offset = l1a_l1s_com.nsync_fbsb.fn_offset;
+ − }
+ − break;
+ − #endif
+ − #if (L1_GPRS)
+ − case PBCCHN_IDLE:
+ − {
+ − cell_info_ptr = &pbcchn_cell_info;
+ − pbcchn_cell_info.radio_freq = l1pa_l1ps_com.pbcchn.bcch_carrier;
+ − pbcchn_cell_info.fn_offset = l1pa_l1ps_com.pbcchn.fn_offset;
+ − }
+ − break;
+ − #endif
+ −
+ − default: return;
+ − }
+ −
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_READ_MSAGC , cell_info_ptr->radio_freq);
+ − #endif
+ −
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET_NEIGH)
+ − buffer_trace(4, l1s.actual_time.fn, cell_info_ptr->radio_freq,
+ − cell_info_ptr->fn_offset, pm);
+ − #endif
+ − #endif
+ −
+ − l1_check_com_mismatch(MS_AGC_ID);
+ −
+ − // Read receive level result from MCU/DSP interface.
+ − // **************************************************
+ − // Read 2 received levels...
+ − #if L1_GPRS
+ − switch (l1a_l1s_com.dsp_scheduler_mode)
+ − {
+ − case GPRS_SCHEDULER:
+ − {
+ − // Call the reading driver using GPRS scheduler
+ − l1pddsp_meas_read(2, pm_level);
+ − } break;
+ −
+ − case GSM_SCHEDULER:
+ − {
+ − // Call the reading driver using GSM scheduler
+ − l1ddsp_meas_read(2, pm_level);
+ − } break;
+ − }
+ − #else
+ − l1ddsp_meas_read(2, pm_level);
+ − #endif
+ −
+ − // Power Measurement performed during last l1s_ctrl_msagc with HIGH_AGC
+ − // returned in pm_level[0]
+ − // Power measurement performed during last l1s_ctrl_msagc with LOW_AGC
+ − // returned in pm_level[1]
+ −
+ − l1_check_pm_error(pm_level[0], MS_AGC_ID);
+ − l1_check_pm_error(pm_level[1], MS_AGC_ID);
+ −
+ − l1ctl_pgc2(pm_level[0], pm_level[1], cell_info_ptr->radio_freq);
+ −
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_LNA)
+ −
+ − #if (L1_FF_MULTIBAND == 0)
+ − buffer_trace (4, 22, cell_info_ptr->radio_freq,
+ − l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].input_level,
+ − l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].lna_off);
+ −
+ − #else // L1_FF_MULTIBAND = 1 below
+ −
+ − operative_radio_freq =
+ − l1_multiband_radio_freq_convert_into_operative_radio_freq(cell_info_ptr->radio_freq);
+ − buffer_trace (4, 22, cell_info_ptr->radio_freq,
+ − l1a_l1s_com.last_input_level[cell_info_ptr->agc_index].input_level,
+ − l1a_l1s_com.last_input_level[cell_info_ptr->agc_index].lna_off);
+ −
+ − #endif // #if (L1_FF_MULTIBAND == 0) else
+ −
+ − #endif
+ − #endif
+ − }
+ −
+ − // Flag the use of the MCU/DSP dual page read interface.
+ − // ******************************************************
+ −
+ − // Set flag used to change the read page at the end of "l1_synch".
+ − l1s_dsp_com.dsp_r_page_used = TRUE;
+ − }
+ −
+ − #if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_read_mon_result() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* tasks: FBNEW,SB1,SB2,SBCONF,SB51,SBCNF51,SB26,SBCNF26.*/
+ − /* This function is the reading result function used for */
+ − /* reading the neighbor cell monitoring results. Here is */
+ − /* a summary of the execution: */
+ − /* */
+ − /* - Traces and debug. */
+ − /* - Get task result from MCU/DSP read interface. */
+ − /* */
+ − /* - case: FBNEW/FB51. */
+ − /* - If SEMAPHORE(task) is low. */
+ − /* - Update AFC if required. */
+ − /* - Read FB detection results. */
+ − /* - Reports results to L1A. */
+ − /* - Disactivate and Disable task. */
+ − /* - Reset buffers and flags in NDB. */
+ − /* */
+ − /* - case: FB26. */
+ − /* - Read FB detection results. */
+ − /* - Reports results to L1A. */
+ − /* - Disactivate task. */
+ − /* */
+ − /* - case: SB26/SBCNF26. */
+ − /* - Read SB reading results. */
+ − /* - Reports results to L1A. */
+ − /* - Disactivate task. */
+ − /* */
+ − /* - case: SB1/SB2/SB51/SBCONF/SBCNF51. */
+ − /* - If SEMAPHORE(task) is low. */
+ − /* - Update AFC if required. */
+ − /* - Read FB detection results. */
+ − /* - Reports results to L1A. */
+ − /* - Disactivate task when required. */
+ − /* */
+ − /* - Flag the use of the MCU/DSP dual page read */
+ − /* interface. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* FBNEW, Frequency Burst detection task in Idle mode. */
+ − /* SB1, Synchro Burst reading task in Idle mode. */
+ − /* SB2, Synchro Burst detection task in Idle mode. */
+ − /* SBCONF, Synchro Burst confirmation task in Idle */
+ − /* mode. */
+ − /* SB51, Synchro Burst reading task in SDCCH Dedicated */
+ − /* mode. */
+ − /* SBCNF51, Synchro Burst confirmation task in SDCCH */
+ − /* Dedicated mode. */
+ − /* SB26, Synchro Burst reading task in TCH Dedicated */
+ − /* mode. */
+ − /* SBCNF26, Synchro Burst confirmation task in TCH */
+ − /* Dedicated mode. */
+ − /* */
+ − /* "attempt_for_sb2" */
+ − /* Since SB2 calls twice this function, this parameter */
+ − /* tells the function which call it it. Used mainly */
+ − /* to know when to DISACTIVATE the task. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.task_param" */
+ − /* task semaphore bit register. Used to skip the body */
+ − /* of this function if L1A has changed or is changing */
+ − /* some of the task parameters. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1a_l1s_com.l1s_en_task" */
+ − /* L1S task enable bit register. */
+ − /* -> disable FBNEW,FB51 task. */
+ − /* */
+ − /* "l1s.task_status[task].current_status" */
+ − /* current task status. It must be reset (INACTIVE) */
+ − /* when the task is completed. */
+ − /* -> disactivate task. */
+ − /* */
+ − /* "l1s_dsp_com.dsp_r_page_used" */
+ − /* Flag used by the function which closes L1S */
+ − /* execution ("l1s_end_manager()") to know if the */
+ − /* MCU/DSP read page must be switched. */
+ − /* -> Set to 1. */
+ − /* */
+ − /* Use of MCU/DSP interface: */
+ − /* ------------------------- */
+ − /* "l1s_dsp_com.dsp_ndb_ptr" */
+ − /* pointer to the non double buffered part (NDB) of */
+ − /* the MCU/DSP interface. This part is R/W for both */
+ − /* DSP and MCU. */
+ − /* */
+ − /* "l1s_dsp_com.dsp_db_r_ptr" */
+ − /* pointer to the double buffered part (DB) of the */
+ − /* MCU/DSP interface. This pointer points to the READ */
+ − /* page. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_read_mon_result(UWORD8 task, UWORD8 attempt)
+ − {
+ − UWORD32 flag=0;
+ − UWORD32 toa;
+ − UWORD32 pm;
+ − UWORD32 angle;
+ − UWORD32 snr;
+ −
+ − #if TESTMODE
+ − UWORD32 pm_fullres;
+ − #endif
+ −
+ − API *data;
+ −
+ − BOOL en_task;
+ − BOOL task_param;
+ − UWORD32 fb_abort_flag=0;
+ −
+ − /*-------------------------------------------------------------------------------*/
+ − /* READ MONITORING TASK RESULTS FROM MCU/DSP INTERFACE... */
+ − /*-------------------------------------------------------------------------------*/
+ − // Get "enable" task flag and "synchro semaphore" for current task.
+ − en_task = l1a_l1s_com.l1s_en_task[task];
+ − task_param = l1a_l1s_com.task_param[task];
+ −
+ − // Traces and debug.
+ − // ******************
+ − #if (TRACE_TYPE!=0)&& (TRACE_TYPE !=5)
+ − trace_fct(CST_L1S_READ_MON_RESULT,(UWORD32)(-1));
+ − #endif
+ −
+ − if(!(en_task) || (task_param))
+ − {
+ − #if (TRACE_TYPE!=0)
+ − // Current task is no more alive, L1A changed the task parameters.
+ − // -> Trace "ABORT" on log file and screen.
+ − trace_fct(CST_TASK_KILLED, (UWORD32)(-1));
+ − #endif
+ − }
+ − else
+ − // Current task is still alive, check task identifier and debug number...
+ − {
+ − #if (TRACE_TYPE!=0)
+ − if((task != FB26) && (task != SB26) && (task != SBCNF26)) // DB cannot be used for FB26/SB26/SBCNF26 result.
+ − if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_md & 0xffff) !=
+ − (UWORD32)DSP_TASK_CODE[task])
+ − // Task id. different than the one expected...
+ − trace_fct(CST_DL_TASKS_DO_NOT_CORRESPOND,(UWORD32)(-1));
+ − #endif
+ −
+ − if((task != FB26) && (task != SB26)
+ − && (task != SBCNF26) && (attempt==12)
+ − #if ((REL99 == 1) && (FF_BHO == 1))
+ − && (task != FBSB)
+ − #endif
+ − ) // DB cannot be used for FB26/SB26/SBCNF26 result.
+ − {
+ − l1_check_com_mismatch(task);
+ − }
+ − }
+ −
+ − // Get task result from MCU/DSP read interface.
+ − // *********************************************
+ −
+ − switch(task)
+ − {
+ − case FBNEW :
+ − case FB51 :
+ − /*---------------------------------------------------*/
+ − /* Frequency burst detection result... */
+ − /*---------------------------------------------------*/
+ − {
+ − if((en_task) && !(task_param))
+ − // Check the task semaphore and the task enable bit. The reading
+ − // task body is executed only when the task semaphore is 0 and the
+ − // task is still enabled.
+ − // The semaphore can be set to 1 whenever L1A makes some changes
+ − // to the task parameters. The task can be disabled by L1A.
+ − {
+ − flag = l1s_dsp_com.dsp_ndb_ptr->d_fb_det & 0xffff; // 1 means FOUND.
+ − toa = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_TOA] & 0xffff; // Unit is BIT.
+ − pm = (l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM] & 0xffff) >> 5;
+ − // WARNING... to be used!!!
+ − #if TESTMODE
+ − pm_fullres = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM] & 0xffff; // F26.6
+ − #endif
+ − angle = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_ANGLE] & 0xffff; // WARNING... to be used!!!
+ − snr = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_SNR] & 0xffff; // WARNING... to be used!!!
+ −
+ −
+ − // Check FB detection flag and attempt:
+ − // If no detection and attempt < 12 than continue FB search
+ − // Attempt=11: special case: wait for next (last) read, as
+ − // other task may already be programmed in MFTAB (do not flush !!!)
+ − if(((!flag) && (attempt < 11)) || (attempt==11))
+ − break;
+ −
+ − // If FB detection occurs before 11th attempt, abort FB search
+ − if((flag == TRUE) && (attempt < 11))
+ − fb_abort_flag=TRUE;
+ −
+ −
+ − if (fb_abort_flag == TRUE)
+ − {
+ − if ((l1s_dsp_com.dsp_db_r_ptr->d_debug & 0xffff) != ((l1s.debug_time + (12 - attempt)) % 65536))
+ − l1_check_com_mismatch(task);
+ − }
+ −
+ − // l1_check_pm_error(pm, task);
+ −
+ − #if TRACE_TYPE==3
+ − stats_samples_fb(flag,toa,pm,angle,snr);
+ − #endif
+ −
+ − #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+ − uart_trace(FB51);
+ − #endif
+ −
+ − // Update AFC: Call AFC control function (KALMAN filter).
+ − #if AFC_ALGO
+ − #if TESTMODE
+ − if (l1_config.afc_enable)
+ − #endif
+ − {
+ − WORD16 old_afc=l1s.afc;
+ −
+ − if((flag == TRUE) && (l1a_l1s_com.mode == CS_MODE))
+ − {
+ − #if (VCXO_ALGO == 0)
+ − l1s.afc = l1ctl_afc(AFC_OPEN_LOOP,
+ − &l1s.afc_frame_count,
+ − (WORD16)angle,
+ − 0,
+ − l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].radio_freq);
+ − #else
+ − l1s.afc = l1ctl_afc(AFC_OPEN_LOOP,
+ − &l1s.afc_frame_count,
+ − (WORD16)angle,
+ − 0,
+ − l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].radio_freq,l1a_l1s_com.mode);
+ − #endif
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_AFC_OPEN)
+ − buffer_trace (4,(WORD16)angle,old_afc,l1s.afc,0);
+ − #endif
+ − #endif
+ − }
+ − }
+ − #endif
+ −
+ − // Call FB report function (send report msg to L1A).
+ − #if TESTMODE
+ − if (l1_config.TestMode)
+ − l1s_read_fb(task, flag, toa, attempt, pm_fullres, angle, snr);
+ − else
+ − l1s_read_fb(task, flag, toa, attempt, pm, angle, snr);
+ − #else
+ − l1s_read_fb(task, flag, toa, attempt, pm, angle, snr);
+ − #endif
+ −
+ − // The Frequency Burst detection task in Idle (FBNEW) and
+ − // Dedicated/SDCCH (FB51) are 1 shot tasks, they must be
+ − // disabled in L1S when they are completed. Disable it.
+ − l1a_l1s_com.l1s_en_task[task] = TASK_DISABLED;
+ −
+ − // the status is not used in D51 and D26 modes
+ − if (task != FB51 )
+ − {
+ − l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].status = NSYNC_COMPLETED;
+ − }
+ − }
+ −
+ − if ((fb_abort_flag == TRUE) || (attempt==12))
+ − {
+ − // FB task is completed, make it INACTIVE.
+ − l1s.task_status[task].current_status = INACTIVE;
+ −
+ − // Reset buffers and flags in NDB ...
+ − l1s_dsp_com.dsp_ndb_ptr->d_fb_det = FALSE;
+ − l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_TOA] = 0;
+ −
+ − // This task is not compatible with Neigh. Measurement.
+ − // Clear "forbid_meas" to indicate when the task is complete.
+ − l1s.forbid_meas = 0;
+ − }
+ −
+ − // FB search finished before 11th attempt:
+ − // -reset DSP R/W pages, DSP tasks and TPU
+ − // -flush MFTAB and reset frame count
+ − // -adjust debug time
+ − if(fb_abort_flag)
+ − {
+ − l1d_reset_hw(l1s.tpu_offset);
+ − l1s.tpu_ctrl_reg |= CTRL_FB_ABORT; // set CTRL bit -> tpu_end_scenario
+ − l1s_clear_mftab(l1s.mftab.frmlst);
+ − l1s.frame_count = 0;
+ −
+ − #if 0 /* FreeCalypso TCS211 reconstruction */
+ − // This task is not compatible with Neigh. Measurement.
+ − // Clear "forbid_meas" to indicate when the task is complete.
+ − l1s.forbid_meas = 0;
+ − #endif
+ − }
+ − }
+ − break;
+ −
+ − case FB26 :
+ − /*---------------------------------------------------*/
+ − /* Frequency burst detection result... */
+ − /*---------------------------------------------------*/
+ − {
+ − UWORD8 neigh_id;
+ −
+ − // read cell identifier.
+ − neigh_id = l1a_l1s_com.nsync.active_fb_id;
+ −
+ − if((en_task) && !(task_param))
+ − // Check the task semaphore and the task enable bit. The reading
+ − // task body is executed only when the task semaphore is 0 and the
+ − // task is still enabled.
+ − // The semaphore can be set to 1 whenever L1A makes some changes
+ − // to the task parameters. The task can be disabled by L1A.
+ − {
+ − flag = l1s_dsp_com.dsp_ndb_ptr->d_fb_det & 0xffff; // 1 means FOUND.
+ − toa = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_TOA] & 0xffff; // Unit is BIT.
+ − pm = (l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM] & 0xffff) >> 5;
+ − // WARNING... to be used!!!
+ − #if TESTMODE
+ − pm_fullres = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM] & 0xffff; // F10.6
+ − #endif
+ −
+ − // CQ 19836: do not check PM on FB26
+ − //l1_check_pm_error(pm, task);
+ −
+ − angle = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_ANGLE] & 0xffff; // WARNING... to be used!!!
+ − snr = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_SNR] & 0xffff; // WARNING... to be used!!!
+ −
+ − // Call FB report function (send report msg to L1A).
+ − #if TESTMODE
+ − if (l1_config.TestMode)
+ − l1s_read_fb(task, flag, toa, NO_PAR, pm_fullres, angle, snr);
+ − else
+ − l1s_read_fb(task, flag, toa, NO_PAR, pm, angle, snr);
+ − #else
+ − l1s_read_fb(task, flag, toa, NO_PAR, pm, angle, snr);
+ − #endif
+ − }
+ −
+ − #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+ − uart_trace(FB26);
+ − #endif
+ −
+ −
+ − // The Frequency Burst detection task in Dedicated/TCH
+ − // is composed with several attempts managed in L1A.
+ − // -> task is completed: set INACTIVE.
+ − l1s.task_status[task].current_status = INACTIVE;
+ −
+ − // Reset buffers and flags in NDB ...
+ − l1s_dsp_com.dsp_ndb_ptr->d_fb_det = FALSE;
+ − l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_TOA] = 0;
+ − }
+ − break;
+ −
+ − case SB26 :
+ − case SBCNF26 :
+ − /*---------------------------------------------------*/
+ − /* Synchro. burst detection result... */
+ − /*---------------------------------------------------*/
+ − {
+ − if((en_task) && !(task_param))
+ − // Check the task semaphore and the task enable bit. The reading
+ − // task body is executed only when the task semaphore is 0 and the
+ −
+ − // task is still enabled.
+ − // The semaphore can be set to 1 whenever L1A makes some changes
+ − // to the task parameters. The task can be disabled by L1A.
+ − {
+ − flag = !(((l1s_dsp_com.dsp_ndb_ptr->a_sch26[0] & 0xffff) & (1<<B_SCH_CRC)) >> B_SCH_CRC); // 1 means ERROR.
+ − toa = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_TOA] & 0xffff; // Unit is BIT.
+ − pm = (l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM] & 0xffff) >> 5;
+ − // WARNING... to be used!!!
+ − #if TESTMODE
+ − pm_fullres = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM] & 0xffff; // F26.6
+ − #endif
+ −
+ − angle = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_ANGLE] & 0xffff;
+ − snr = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_SNR] & 0xffff;
+ − data = &(l1s_dsp_com.dsp_ndb_ptr->a_sch26[3]); // Set data block pointer (skip header).
+ −
+ − l1_check_pm_error(pm, task);
+ −
+ − // Call SB report function (send report msg to L1A).
+ − #if TESTMODE
+ − if (l1_config.TestMode)
+ − l1s_read_sb(task, flag, data, toa, attempt, pm_fullres, angle, snr);
+ − else
+ − l1s_read_sb(task, flag, data, toa, attempt, pm, angle, snr);
+ − #else
+ − l1s_read_sb(task, flag, data, toa, attempt, pm, angle, snr);
+ − #endif
+ − }
+ − #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+ − uart_trace(SB26);
+ − #endif
+ −
+ −
+ − // The Synchro Burst detection (SB26) and confirmation (SBCNF26)
+ − // tasks in Dedicated/TCH are enabling/disabling are fully
+ − // managed by L1A.
+ − // -> task is completed: set INACTIVE.
+ − l1s.task_status[task].current_status = INACTIVE;
+ −
+ − // Reset buffers and flags in NDB ...
+ − l1s_dsp_com.dsp_ndb_ptr->a_sch26[0] = (1<<B_SCH_CRC);
+ − }
+ − break;
+ −
+ − case SB2 :
+ − case SBCONF :
+ − case SB51 :
+ − case SBCNF51 :
+ − /*---------------------------------------------------*/
+ − /* Synchro. burst detection result... */
+ − /*---------------------------------------------------*/
+ − {
+ − if((en_task) && !(task_param))
+ − // Check the task semaphore and the task enable bit. The reading
+ − // task body is executed only when the task semaphore is 0 and the
+ − // task is still enabled.
+ − // The semaphore can be set to 1 whenever L1A makes some changes
+ − // to the task parameters. The task can be disabled by L1A.
+ − {
+ − UWORD8 neigh_id;
+ −
+ − if((task == SB2) || (task == SB51))
+ − neigh_id = l1a_l1s_com.nsync.active_sb_id;
+ − else
+ − neigh_id = l1a_l1s_com.nsync.active_sbconf_id;
+ −
+ − flag = !(((l1s_dsp_com.dsp_db_r_ptr->a_sch[0] & 0xffff) & (1<<B_SCH_CRC)) >> B_SCH_CRC); // 1 means ERROR.
+ − toa = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_TOA] & 0xffff; // Unit is BIT.
+ − pm = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM] & 0xffff) >> 5;
+ − // WARNING... to be used!!!
+ − #if TESTMODE
+ − pm_fullres = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM] & 0xffff; // F26.6
+ − #endif
+ −
+ − angle = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_ANGLE] & 0xffff;
+ − snr = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_SNR] & 0xffff;
+ − data = &(l1s_dsp_com.dsp_db_r_ptr->a_sch[3]); // Set data block pointer (skip header).
+ −
+ − #if (L1_DEBUG_IQ_DUMP == 1)
+ − l1ddsp_read_iq_dump(task);
+ − #endif
+ −
+ − l1_check_pm_error(pm, task);
+ −
+ − // CQ30474. In case SNR is too low, the SB shall be considered as failed.
+ − // This is valuable for code running on target with DSP 3606.
+ −
+ − /*
+ − * FreeCalypso: despite the above comment,
+ − * this code is NOT present in TCS211.
+ − */
+ − #if 0
+ − #if (CODE_VERSION == NOT_SIMULATION)
+ − if ( snr < MIN_ACCEPTABLE_SNR_FOR_SB )
+ − flag = FALSE;
+ − #endif
+ − #endif
+ −
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET_NEIGH)
+ − buffer_trace(4, l1s.actual_time.fn, toa,pm, l1s_dsp_com.dsp_db_r_ptr->a_sch[0] & 0xffff);
+ − #endif
+ − #endif
+ −
+ − #if TRACE_TYPE==3
+ − stats_samples_sb(flag,toa,pm,angle,snr);
+ − #endif
+ − #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+ − if (task == SBCONF) uart_trace(SBCONF);
+ − else uart_trace(SB2); // display result code...
+ − #endif
+ −
+ − // Update AFC: Call AFC control function (KALMAN filter).
+ − #if AFC_ALGO
+ − #if TESTMODE
+ − if (l1_config.afc_enable)
+ − #endif
+ − {
+ − WORD16 old_afc=l1s.afc;
+ −
+ − if((flag == TRUE) && (l1a_l1s_com.mode == CS_MODE))
+ − {
+ − #if (VCXO_ALGO == 0)
+ − l1s.afc = l1ctl_afc(AFC_OPEN_LOOP,
+ − &l1s.afc_frame_count,
+ − (WORD16)angle,
+ − 0,
+ − l1a_l1s_com.nsync.list[neigh_id].radio_freq);
+ − #else
+ − l1s.afc = l1ctl_afc(AFC_OPEN_LOOP,
+ − &l1s.afc_frame_count,
+ − (WORD16)angle,
+ − 0,
+ − l1a_l1s_com.nsync.list[neigh_id].radio_freq,l1a_l1s_com.mode);
+ − #endif
+ −
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_AFC_OPEN)
+ − buffer_trace (4,(WORD16)angle,old_afc,l1s.afc,1);
+ − #endif
+ − #endif
+ − }
+ − }
+ − #endif
+ −
+ − // Call SB report function (send report msg to L1A).
+ − #if TESTMODE
+ − if (l1_config.TestMode)
+ − l1s_read_sb(task, flag, data, toa, attempt, pm_fullres, angle, snr);
+ − else
+ − l1s_read_sb(task, flag, data, toa, attempt, pm, angle, snr);
+ − #else
+ − l1s_read_sb(task, flag, data, toa, attempt, pm, angle, snr);
+ − #endif
+ −
+ − // the status is not used in D51 and D26 modes
+ − if ((task != SBCNF51 ) && (task != SB51))
+ − {
+ − // SB2 activity completed for this neighbour cell.
+ − if((task != SB2) || ((task == SB2) && (attempt == 2)))
+ − l1a_l1s_com.nsync.list[neigh_id].status = NSYNC_COMPLETED;
+ − }
+ − }
+ −
+ − // All tasks are completed by this function except SB2 which
+ − // calls it twice. SB2 is then completed only when making the
+ − // second execution of this function.
+ − // -> task is completed: set INACTIVE.
+ − if((task != SB2) || (task == SB2) && (attempt == 2))
+ − {
+ − l1s.task_status[task].current_status = INACTIVE;
+ − l1a_l1s_com.l1s_en_task[task] = TASK_DISABLED;
+ − }
+ − }
+ − break;
+ − #if ((REL99 == 1) && (FF_BHO == 1))
+ − case FBSB :
+ −
+ − /*---------------------------------------------------*/
+ − /* Frequency + Synchro burst detection result... */
+ − /*---------------------------------------------------*/
+ − {
+ − BOOL abort_flag = FALSE;
+ −
+ − if (l1a_l1s_com.nsync_fbsb.fb_found_attempt == 0)
+ − // Looking for FB
+ − {
+ − flag = l1s_dsp_com.dsp_ndb_ptr->d_fb_det & 0xffff; // flag = TRUE means FOUND.
+ − toa = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_TOA] & 0xffff; // Unit is BIT.
+ − pm = (l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM] & 0xffff) >> 5;
+ − #if TESTMODE
+ − pm_fullres = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM] & 0xffff; // F26.6
+ − #endif
+ − angle = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_ANGLE] & 0xffff;
+ − snr = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_SNR] & 0xffff;
+ −
+ − if (flag) // FB detected
+ − {
+ − // Store toa and attempt for future use
+ − l1a_l1s_com.nsync_fbsb.fb_toa = toa;
+ − l1a_l1s_com.nsync_fbsb.fb_found_attempt = attempt;
+ −
+ − #if (TRACE_TYPE == 3)
+ − stats_samples_fb(flag, toa, pm, angle, snr);
+ − #endif
+ −
+ − #if (TRACE_TYPE == 2 ) || (TRACE_TYPE == 3)
+ − // uart_trace(FBSB);
+ − #endif
+ − }
+ − else
+ − {
+ − if (attempt < 12)
+ − {
+ − // FB not found, some attempts remaining
+ − break;
+ − }
+ − else
+ − {
+ − // FB not found, no attempt remaining
+ − // Call FBSB report function (send report msg to L1A).
+ − #if TESTMODE
+ − if (l1_config.TestMode)
+ − l1s_read_fbsb(task, attempt, FALSE, FALSE, (API *)NULL, toa, pm, angle, snr);
+ − else
+ − #endif
+ − l1s_read_fbsb(task, attempt, FALSE, FALSE, (API *)NULL, toa, pm, angle, snr);
+ −
+ − abort_flag = TRUE;
+ − }
+ − }
+ − }
+ − else // if (l1a_l1s_com.nsync_fbsb.fb_found_attempt == 0)
+ − // Looking for SB
+ − {
+ − flag = !(((l1s_dsp_com.dsp_db_r_ptr->a_sch[0] & 0xffff) & (1<<B_SCH_CRC)) >> B_SCH_CRC); // // flag = TRUE means FOUND.
+ − toa = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_TOA] & 0xffff; // Unit is BIT.
+ − pm = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM] & 0xffff) >> 5;
+ − #if TESTMODE
+ − pm_fullres = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM] & 0xffff; // F26.6
+ − #endif
+ − angle = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_ANGLE] & 0xffff;
+ − snr = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_SNR] & 0xffff;
+ − data = &(l1s_dsp_com.dsp_db_r_ptr->a_sch[3]); // Set data block pointer (skip header).
+ −
+ − if (flag) // SB detected
+ − {
+ − // SB found report SUCCESS
+ −
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET_NEIGH)
+ − buffer_trace(4, l1s.actual_time.fn, toa,pm, l1s_dsp_com.dsp_db_r_ptr->a_sch[0] & 0xffff);
+ − #endif
+ − #endif
+ −
+ − #if (TRACE_TYPE == 3)
+ − stats_samples_sb(flag, toa, pm, angle, snr);
+ − #endif
+ −
+ − #if (TRACE_TYPE == 2 ) || (TRACE_TYPE == 3)
+ − // uart_trace(FBSB); // display result code...
+ − #endif
+ −
+ − // Call FBSB report function (send report msg to L1A).
+ − #if TESTMODE
+ − if (l1_config.TestMode)
+ − l1s_read_fbsb(task, attempt, TRUE, TRUE, data, toa, pm, angle, snr);
+ − else
+ − #endif
+ − l1s_read_fbsb(task, attempt, TRUE, TRUE, data, toa, pm, angle, snr);
+ −
+ − abort_flag = TRUE;
+ − }
+ − else // if (flag)
+ − {
+ − if (attempt < (l1a_l1s_com.nsync_fbsb.fb_found_attempt + 2))
+ − {
+ − // SB not found, one attempt remaining
+ − break;
+ − }
+ − else
+ − {
+ − // SB not found, no attempt remaining
+ − // Call FBSB report function (send report msg to L1A).
+ − #if TESTMODE
+ − if (l1_config.TestMode)
+ − l1s_read_fbsb(task, attempt, TRUE, FALSE, (API *)NULL, toa, pm, angle, snr);
+ − else
+ − #endif
+ − l1s_read_fbsb(task, attempt, TRUE, FALSE, (API *)NULL, toa, pm, angle, snr);
+ −
+ − abort_flag = TRUE;
+ − }
+ − }
+ − } // if(l1a_l1s_com.nsync_fbsb.fb_found_attempt == 0)
+ −
+ −
+ − if(abort_flag == TRUE)
+ − {
+ − // -> task is completed: set INACTIVE.
+ − l1s.task_status[task].current_status = INACTIVE;
+ − l1a_l1s_com.l1s_en_task[task] = TASK_DISABLED;
+ −
+ − if (attempt < 14)
+ − {
+ − // FBSB search finished before last attempt:
+ − // -reset DSP R/W pages, DSP tasks and TPU
+ − // -flush MFTAB and reset frame count
+ − // -adjust debug time
+ − l1d_reset_hw(l1s.tpu_offset);
+ − l1s.tpu_ctrl_reg |= CTRL_FBSB_ABORT; // set CTRL bit -> tpu_end_scenario
+ − l1s_clear_mftab(l1s.mftab.frmlst);
+ − l1s.frame_count = 0;
+ − }
+ − }
+ − }
+ − #endif // #if ((REL99 == 1) && (FF_BHO == 1))
+ − }
+ −
+ − // Flag the use of the MCU/DSP dual page read interface.
+ − // ******************************************************
+ −
+ − // Set flag used to change the read page at the end of "l1_synch" only if not
+ − // in dedicated/TCH mode (FB26,SB26,SBCNF26). Those task are not following the
+ − // common principle. They use only the NDB part of the MCU/DSP interface, no
+ − // page swapping is then needed.
+ − #if ((REL99 == 1) && (FF_BHO == 1))
+ − if(((task != FB26) && (task != SB26) && (task != SBCNF26) && (task != FBNEW) && (task != FB51) && (task != FBSB)) ||
+ − #else
+ − if(((task != FB26) && (task != SB26) && (task != SBCNF26) && (task != FBNEW) && (task != FB51)) ||
+ − #endif // #if ((REL99 == 1) && (FF_BHO == 1))
+ − ((!fb_abort_flag) && (attempt==12)))
+ − l1s_dsp_com.dsp_r_page_used = TRUE;
+ − }
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+ − #endif // MOVE_IN_INTERNAL_RAM
+ −
+ − #if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM !=0)) // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM enabled
+ − //#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_START // KEEP IN EXTERNAL MEM otherwise
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_read_snb_dl() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* tasks: BCCHS,NP,EP,ALLC,SMSCB. */
+ − /* This function is the reading result function used for */
+ − /* reading a serving cell burst acquisition result in */
+ − /* any mode except dedicated mode. Here is a summary of */
+ − /* the execution: */
+ − /* */
+ − /* - If SEMAPHORE(task) is low and task still enabled. */
+ − /* - Traces and debug. */
+ − /* - Read control results and feed control algo. */
+ − /* - Read DL DATA block from MCU/DSP interface. */
+ − /* - Disactivate task. */
+ − /* - Flag the use of the MCU/DSP dual page read */
+ − /* interface. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* NP, Normal paging reading task. */
+ − /* EP, Extended paging reading task. */
+ − /* BCCHS, BCCH Serving reading task. */
+ − /* ALLC, All serving cell CCCH reading task. */
+ − /* SMSCB, Short Message Service Cell Broadcast task. */
+ − /* */
+ − /* "burst_id" */
+ − /* BURST_1, 1st burst of the task. */
+ − /* BURST_2, 2nd burst of the task. */
+ − /* BURST_3, 3rd burst of the task. */
+ − /* BURST_4, 4th burst of the task. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.task_param" */
+ − /* task semaphore bit register. Used to skip the body */
+ − /* of this function if L1A has changed or is changing */
+ − /* some of the task parameters. */
+ − /* */
+ − /* "l1a_l1s_com.l1s_en_task" */
+ − /* L1S task enable bit register. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.task_status[task].current_status" */
+ − /* current task status. It must be reset (INACTIVE) */
+ − /* when the task is completed. */
+ − /* -> disactivate task. */
+ − /* */
+ − /* "l1s_dsp_com.dsp_r_page_used" */
+ − /* Flag used by the function which closes L1S */
+ − /* execution ("l1s_end_manager()") to know if the */
+ − /* MCU/DSP read page must be switched. */
+ − /* -> Set to 1. */
+ − /* */
+ − /* Use of MCU/DSP interface: */
+ − /* ------------------------- */
+ − /* "l1s_dsp_com.dsp_ndb_ptr" */
+ − /* pointer to the non double buffered part (NDB) of */
+ − /* the MCU/DSP interface. This part is R/W for both */
+ − /* DSP and MCU. */
+ − /* */
+ − /* "l1s_dsp_com.dsp_db_r_ptr" */
+ − /* pointer to the double buffered part (DB) of the */
+ − /* MCU/DSP interface. This pointer points to the READ */
+ − /* page. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_read_snb_dl(UWORD8 task, UWORD8 burst_id)
+ − {
+ − UWORD32 toa;
+ − UWORD32 pm;
+ − UWORD32 angle;
+ − UWORD32 snr;
+ − BOOL en_task;
+ − BOOL task_param;
+ − UWORD16 radio_freq=0;
+ − static UWORD16 pwr_level;
+ − #if L1_FF_MULTIBAND == 1
+ − UWORD16 operative_radio_freq;
+ − #endif
+ −
+ − #if (FF_L1_FAST_DECODING == 1)
+ − UWORD8 skipped_bursts = 0;
+ − BOOL fast_decoding_authorized = l1s_check_fast_decoding_authorized(task);
+ − BOOL fast_decoded = (l1a_apihisr_com.fast_decoding.status == C_FAST_DECODING_COMPLETE);
+ − if (fast_decoded)
+ − {
+ − skipped_bursts = BURST_4 - burst_id;
+ − }
+ − #endif /* if (FF_L1_FAST_DECODING == 1) */
+ −
+ − /*--------------------------------------------------------*/
+ − /* READ SERVING CELL RECEIVE TASK RESULTS... */
+ − /*--------------------------------------------------------*/
+ − /* Rem: only a partial result is present in the mcu<-dsp */
+ − /* communication buffer. The DATA BLOCK content itself is */
+ − /* in the last comm. (BURST_4) */
+ − /*--------------------------------------------------------*/
+ − // Get "enable" task flag and "synchro semaphore" for current task.
+ − en_task = l1a_l1s_com.l1s_en_task[task];
+ − task_param = l1a_l1s_com.task_param[task];
+ −
+ − if((en_task) && !(task_param))
+ − // Check the task semaphore and the task enable bit. The reading
+ − // task body is executed only when the task semaphore is 0 and the
+ − // task is still enabled.
+ − // The semaphore can be set to 1 whenever L1A makes some changes
+ − // to the task parameters. The task can be disabled by L1A.
+ − {
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+ − trace_fct(CST_L1S_READ_SNB_DL , (UWORD32)(-1));//OMAPS00090550
+ − #endif
+ −
+ − #if (TRACE_TYPE!=0)
+ − #if L1_GPRS
+ − if (l1a_l1s_com.dsp_scheduler_mode == GSM_SCHEDULER)
+ − {
+ − // Check task identifier...
+ − if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_d & 0xffff) != (UWORD32)DSP_TASK_CODE[task])
+ − trace_fct(CST_DL_TASKS_DO_NOT_CORRESPOND, (UWORD32)(-1));//OMAPS00090550
+ −
+ − // Check burst identifier...
+ − if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_burst_d & 0xffff) != burst_id)
+ − trace_fct(CST_DL_BURST_DOES_NOT_CORRESPOND, (UWORD32)(-1));//OMAPS00090550
+ − }
+ − else // GPRS scheduler
+ − {
+ − // Check burst identifier...
+ − if(l1ps_dsp_com.pdsp_db_r_ptr->d_burst_nb_gprs != burst_id)
+ − trace_fct(CST_DL_BURST_DOES_NOT_CORRESPOND, (UWORD32)(-1));
+ − }
+ − #else
+ − // Check task identifier...
+ − if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_d & 0xffff) != (UWORD32)DSP_TASK_CODE[task])
+ − trace_fct(CST_DL_TASKS_DO_NOT_CORRESPOND, (UWORD32)(-1));
+ −
+ − // Check burst identifier...
+ − if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_burst_d & 0xffff) != burst_id)
+ − trace_fct(CST_DL_BURST_DOES_NOT_CORRESPOND,(UWORD32)( -1));
+ − #endif
+ − #endif
+ −
+ − l1_check_com_mismatch(task);
+ −
+ − // Read control results and feed control algorithms.
+ − // **************************************************
+ −
+ − // Read control information.
+ − #if L1_GPRS
+ − if (l1a_l1s_com.dsp_scheduler_mode == GSM_SCHEDULER)
+ − {
+ − toa = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_TOA] & 0xffff;
+ − pm = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM] & 0xffff) >> 5;
+ − angle = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_ANGLE] & 0xffff;
+ − snr = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_SNR] & 0xffff;
+ − }
+ − else
+ − {
+ − toa = l1ps_dsp_com.pdsp_db_r_ptr->a_burst_toa_gprs[0] & 0xffff;
+ − pm = (l1ps_dsp_com.pdsp_db_r_ptr->a_burst_pm_gprs[0] & 0xffff) >> 5;
+ − angle = l1ps_dsp_com.pdsp_db_r_ptr->a_burst_angle_gprs[0] & 0xffff;
+ − snr = l1ps_dsp_com.pdsp_db_r_ptr->a_burst_snr_gprs[0] & 0xffff;
+ − }
+ − #else
+ − toa = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_TOA] & 0xffff;
+ − pm = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM] & 0xffff) >> 5;
+ − angle = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_ANGLE] & 0xffff;
+ − snr = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_SNR] & 0xffff;
+ − #endif
+ −
+ − l1_check_pm_error(pm, task);
+ −
+ − // Update AGC: Call PAGC algorithm
+ − radio_freq = l1a_l1s_com.Scell_info.radio_freq;
+ −
+ − #if (L1_FF_MULTIBAND == 0)
+ −
+ − l1a_l1s_com.Scell_IL_for_rxlev = l1ctl_pagc((UWORD8)pm, radio_freq,
+ − &l1a_l1s_com.last_input_level[radio_freq - l1_config.std.radio_freq_index_offset]);
+ − #else // L1_FF_MULTIBAND = 1 below
+ −
+ − operative_radio_freq =
+ − l1_multiband_radio_freq_convert_into_operative_radio_freq(radio_freq);
+ − l1a_l1s_com.Scell_IL_for_rxlev = l1ctl_pagc((UWORD8)pm, radio_freq,
+ − &l1a_l1s_com.last_input_level[operative_radio_freq]);
+ −
+ − #endif // #if (L1_FF_MULTIBAND == 0) else
+ −
+ −
+ − #if (FF_L1_FAST_DECODING == 1)
+ − if (skipped_bursts>0)
+ − {
+ − l1ctl_pagc_missing_bursts(skipped_bursts);
+ − }
+ − #endif /* if (FF_L1_FAST_DECODING == 1) */
+ −
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_LNA)
+ −
+ − #if (L1_FF_MULTIBAND == 0)
+ − buffer_trace (4, 33, radio_freq,
+ − l1a_l1s_com.last_input_level[radio_freq - l1_config.std.radio_freq_index_offset].input_level,
+ − l1a_l1s_com.last_input_level[radio_freq - l1_config.std.radio_freq_index_offset].lna_off);
+ −
+ − #else // L1_FF_MULTIBAND = 1 below
+ −
+ − buffer_trace (4, 33, radio_freq,
+ − l1a_l1s_com.last_input_level[operative_radio_freq].input_level,
+ − l1a_l1s_com.last_input_level[operative_radio_freq].lna_off);
+ −
+ − #endif // #if (L1_FF_MULTIBAND == 0) else
+ −
+ − #endif
+ − #endif
+ −
+ − #if TRACE_TYPE==3
+ − stats_samples_nb(toa,pm,angle,snr,burst_id,task);
+ − #endif
+ −
+ − // Update AFC: Call AFC control function (KALMAN filter).
+ − #if AFC_ALGO
+ − #if TESTMODE
+ − if (l1_config.afc_enable)
+ − #endif
+ − {
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_AFC_OPEN)//omaps00090550
+ − WORD16 old_afc = l1s.afc;
+ − WORD16 old_count= l1s.afc_frame_count;
+ − #endif
+ − #endif
+ −
+ −
+ −
+ − #if (VCXO_ALGO == 0)
+ − l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq);
+ − #else
+ − l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq,l1a_l1s_com.mode);
+ − #endif
+ −
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_AFC_OPEN)
+ − buffer_trace (4,(WORD16)angle,old_count,old_afc,l1s.afc);
+ − #endif
+ − #if (DEBUG_TRACE == BUFFER_TRACE_TOA)
+ − if (task == NP || task == EP)
+ − buffer_trace(5,
+ − l1s.debug_time,
+ − 0xf1,
+ − i,
+ − l1s.afc,
+ − angle );
+ − #endif
+ − #endif
+ − }
+ − #endif
+ −
+ − //Feed TOA histogram.
+ − #if (TOA_ALGO != 0)
+ − if (task != SMSCB)
+ − {
+ − #if (TOA_ALGO == 2)
+ − if(l1s.toa_var.toa_snr_mask == 0)
+ − #else
+ − if(l1s.toa_snr_mask == 0)
+ − #endif
+ − #if (RF_FAM == 2) // RF 2
+ − #if (TOA_ALGO == 2)
+ − if(l1a_l1s_com.Scell_IL_for_rxlev < IL_FOR_RXLEV_SNR)
+ − {
+ − l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa);
+ − }
+ − else
+ − {
+ − l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa);
+ − }
+ − #else
+ − if(l1a_l1s_com.Scell_IL_for_rxlev <IL_FOR_RXLEV_SNR)
+ − {
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa, &l1s.toa_update, &l1s.toa_period_count
+ − #if (FF_L1_FAST_DECODING == 1)
+ − , skipped_bursts
+ − #endif
+ − );
+ − }
+ − else
+ − {
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa, &l1s.toa_update, &l1s.toa_period_count
+ − #if (FF_L1_FAST_DECODING == 1)
+ − , skipped_bursts
+ − #endif
+ − );
+ − }
+ − #endif
+ −
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_TOA )
+ − if (task == NP || task == EP)
+ − buffer_trace(5,
+ − l1s.debug_time,
+ − 0xf0,
+ − toa,
+ − snr,
+ − l1s.tpu_offset );
+ − #endif
+ − #endif
+ − #else // RF 2
+ − #if (TOA_ALGO == 2)
+ − if(l1a_l1s_com.Scell_IL_for_rxlev < IL_FOR_RXLEV_SNR)
+ − {
+ − l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa);
+ − }
+ − else
+ − {
+ − l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa);
+ − }
+ − #else
+ − if(l1a_l1s_com.Scell_IL_for_rxlev <IL_FOR_RXLEV_SNR)
+ − {
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa, &l1s.toa_update, &l1s.toa_period_count
+ − #if (FF_L1_FAST_DECODING == 1)
+ − , skipped_bursts
+ − #endif
+ − );
+ − }
+ − else
+ − {
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa, &l1s.toa_update, &l1s.toa_period_count
+ − #if (FF_L1_FAST_DECODING ==1)
+ − , skipped_bursts
+ − #endif
+ − );
+ − }
+ − #endif
+ − #endif // RF 2
+ − }
+ − #else // TOA_ALGO
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_TOA)
+ − if (task == NP || task == EP)
+ − buffer_trace(5,
+ − l1s.debug_time,
+ − 0xf0,
+ − toa,
+ − snr,
+ − l1s.tpu_offset );
+ − #endif
+ − #endif
+ − #endif // TOA_ALGO
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − RTTL1_FILL_DL_BURST(angle, snr, l1s.afc, task, pm, toa, l1a_l1s_com.Scell_IL_for_rxlev)
+ − #endif
+ − #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4)) && HAVE_L1_TRACE_BURST_PARAM
+ − l1_trace_burst_param(angle, snr, l1s.afc, task, pm, toa, l1a_l1s_com.Scell_IL_for_rxlev);
+ − #endif
+ − #if (BURST_PARAM_LOG_ENABLE == 1)
+ − l1_log_burst_param(angle, snr, l1s.afc, task, pm, toa, l1a_l1s_com.Scell_IL_for_rxlev);
+ − #endif
+ −
+ − // compute the Data bloc Power.
+ − // ******************************
+ − if(burst_id == BURST_1)
+ − pwr_level = 0;
+ −
+ − // add the burst power
+ − pwr_level += l1a_l1s_com.Scell_IL_for_rxlev;
+ −
+ −
+ − // Read downlink DATA block from MCU/DSP interface.
+ −
+ − if (task == NP)
+ − {
+ − toa_tab[burst_id] = toa;
+ − }
+ −
+ − #if 0 /* FreeCalypso TCS211 reconstruction */
+ − // added Enhanced RSSI
+ − if(l1s_dsp_com.dsp_ndb_ptr->a_cd[2] != 0xffff)
+ − {
+ − qual_acc_idle1[0] += l1s_dsp_com.dsp_ndb_ptr->a_cd[2];
+ − //RX Qual value reporting- total number of decoded bits
+ − qual_acc_idle1[1] += 1;
+ − }
+ − #endif
+ −
+ − #if (FF_L1_FAST_DECODING == 1)
+ − /* Perform the reporting if
+ − - Burst is the 4th one (whether CRC is ok or not)
+ − - Fast decoding enabled and CRC already ok
+ − */
+ − if ( (burst_id == BURST_4) || fast_decoded )
+ − #else /* #if (FF_L1_FAST_DECODING == 1) */
+ − if(burst_id == BURST_4)
+ − #endif /* FF_L1_FAST_DECODING */
+ − {
+ − UWORD8 i;
+ −
+ − #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+ − uart_trace(task);
+ − #endif
+ −
+ − // the data power bloc = pwr_level/4.
+ − #if (FF_L1_FAST_DECODING == 1)
+ − /* Data power block = pwr_level / (nb of bursts)*/
+ − pwr_level = pwr_level / (burst_id + 1);
+ − #else /* #if (FF_L1_FAST_DECODING == 1) */
+ − // the data power bloc = pwr_level/4.
+ − pwr_level = pwr_level >> 2;
+ − #endif /* #if (FF_L1_FAST_DECODING == 1) #else*/
+ −
+ − #if (FF_L1_FAST_DECODING == 1)
+ − if(!fast_decoding_authorized)
+ − {
+ − /* When fast decoding wasn't used, burst_id is undefined (for the trace) */
+ − l1a_l1s_com.last_fast_decoding = 0;
+ − }
+ − else
+ − {
+ − l1a_l1s_com.last_fast_decoding = burst_id + 1;
+ − }
+ − #endif /* #if (FF_L1_FAST_DECODING == 1) */
+ −
+ − // Read L3 frame block and send msg to L1A.
+ − #if L1_GPRS
+ − if (l1a_l1s_com.dsp_scheduler_mode == GSM_SCHEDULER)
+ − l1s_read_l3frm(pwr_level,&(l1s_dsp_com.dsp_ndb_ptr->a_cd[0]), task);
+ − else
+ − l1s_read_l3frm(pwr_level,&(l1ps_dsp_com.pdsp_ndb_ptr->a_dd_gprs[0][0]), task);
+ − #else
+ − l1s_read_l3frm(pwr_level,&(l1s_dsp_com.dsp_ndb_ptr->a_cd[0]), task);
+ − #endif
+ −
+ − #if L1_GPRS
+ − if (l1a_l1s_com.dsp_scheduler_mode == GSM_SCHEDULER)
+ − #endif
+ − {
+ − // reset buffers and flags in NDB ...
+ − // reset nerr....
+ − // reset A_CD contents.......
+ − l1s_dsp_com.dsp_ndb_ptr->a_cd[2] = 0xffff;
+ − for (i=0;i<12;i++)
+ − l1s_dsp_com.dsp_ndb_ptr->a_cd[3+i] = 0x0000;
+ − }
+ −
+ − } // End if...
+ − } // End if...
+ −
+ − // The NP/EP task was enabled and could cancel a PTCCH burst
+ − // This incomplete PTCCH decoding block cause DSP troubles and so COM/PM errors
+ − // and then a recovery => in this case restart the PTCCH from the burst 0
+ − #if L1_GPRS
+ − if((task == NP)||(task == EP))
+ − if(l1a_l1s_com.l1s_en_task[PTCCH] == TASK_ENABLED)
+ − if(l1pa_l1ps_com.transfer.ptcch.activity & PTCCH_DL) // a PTCCH DL task is running
+ − if((l1s.actual_time.t2 >= 13) && (l1s.actual_time.t2 <= 17)) // only if the NP/EP remove a PTCCH activity
+ − {
+ − // Restart PTCCH DL task from the begining (i.e BURST 0).
+ − l1pa_l1ps_com.transfer.ptcch.activity ^= PTCCH_DL; // disable PTCCH_DL activity running
+ − l1pa_l1ps_com.transfer.ptcch.request_dl = TRUE; // restart PTCCH DL from the Burst0
+ − }
+ − #endif
+ −
+ − // Deactivate task.
+ − // ******************
+ −
+ − // End of task -> task must become INACTIVE.
+ − // Rem: some TASKS (ALLC) can be pipelined and therefore must stay active if
+ − // they have already reentered the flow.
+ − #if (FF_L1_FAST_DECODING == 1)
+ − if ( (burst_id == BURST_4) || fast_decoded )
+ − #else /* #if (FF_L1_FAST_DECODING == 1) */
+ − if(burst_id == BURST_4)
+ − #endif /* #if (FF_L1_FAST_DECODING == 1) #else*/
+ −
+ − {
+ − #if (FF_L1_FAST_DECODING == 1)
+ − if((task == NP) || (task == NBCCHS))
+ − {
+ − if (l1a_apihisr_com.fast_decoding.contiguous_decoding == TRUE)
+ − {
+ − /* A new block has started, a new fast API IT is expected */
+ − l1a_apihisr_com.fast_decoding.contiguous_decoding = FALSE;
+ − l1a_apihisr_com.fast_decoding.status = C_FAST_DECODING_AWAITED;
+ − }
+ − else if(task == l1a_apihisr_com.fast_decoding.task)
+ − {
+ − /* Reset decoding status */
+ − l1a_apihisr_com.fast_decoding.status = C_FAST_DECODING_NONE;
+ − }
+ − } /* end if tsk == NP */
+ − #endif /* #if (FF_L1_FAST_DECODING == 1) */
+ − if(l1s.task_status[task].current_status == RE_ENTERED)
+ − l1s.task_status[task].current_status = ACTIVE;
+ − else
+ − l1s.task_status[task].current_status = INACTIVE;
+ − #if (FF_L1_FAST_DECODING == 1)
+ − if (burst_id != BURST_4)
+ − {
+ − /* Successful decode before the 4th burst, no other control/read activities are needed */
+ − l1s_clean_mftab(task, burst_id + 3);
+ − if(l1s.frame_count == (4 -burst_id))
+ − {
+ − l1s.frame_count = 1;
+ − }
+ − }
+ − #endif /* #if (FF_L1_FAST_DECODING == 1) */
+ − }
+ −
+ − #if (L1_DEBUG_IQ_DUMP == 1)
+ − l1ddsp_read_iq_dump(task);
+ − #endif
+ −
+ − // Flag the use of the MCU/DSP dual page read interface.
+ − // ******************************************************
+ −
+ − // Set flag used to change the read page at the end of "l1_synch".
+ − l1s_dsp_com.dsp_r_page_used = TRUE;
+ − }
+ −
+ −
+ − //#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END
+ − #endif
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_read_nnb() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* tasks: BCCHN. */
+ − /* This function is the reading result function used for */
+ − /* reading a neighbor cell block acquisition result in */
+ − /* idle mode. Here is a summary of the execution: */
+ − /* */
+ − /* - If SEMAPHORE(task) is low and task still enabled. */
+ − /* - Traces and debug. */
+ − /* - Read DL DATA block from MCU/DSP interface. */
+ − /* - Disactivate task. */
+ − /* - Flag the use of the MCU/DSP dual page read */
+ − /* interface. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* BCCHN, BCCH Neighbor reading task. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.task_param" */
+ − /* task semaphore bit register. Used to skip the body */
+ − /* of this function if L1A has changed or is changing */
+ − /* some of the task parameters. */
+ − /* */
+ − /* "l1a_l1s_com.l1s_en_task" */
+ − /* L1S task enable bit register. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.task_status[task].current_status" */
+ − /* current task status. It must be reset (INACTIVE) */
+ − /* when the task is completed. */
+ − /* -> disactivate task. */
+ − /* */
+ − /* "l1s_dsp_com.dsp_r_page_used" */
+ − /* Flag used by the function which closes L1S */
+ − /* execution ("l1s_end_manager()") to know if the */
+ − /* MCU/DSP read page must be switched. */
+ − /* -> Set to 1. */
+ − /* */
+ − /* Use of MCU/DSP interface: */
+ − /* ------------------------- */
+ − /* "l1s_dsp_com.dsp_ndb_ptr" */
+ − /* pointer to the non double buffered part (NDB) of */
+ − /* the MCU/DSP interface. This part is R/W for both */
+ − /* DSP and MCU. */
+ − /* */
+ − /* "l1s_dsp_com.dsp_db_r_ptr" */
+ − /* pointer to the double buffered part (DB) of the */
+ − /* MCU/DSP interface. This pointer points to the READ */
+ − /* page. */
+ − /* */
+ − /*-------------------------------------------------------*/
+ − void l1s_read_nnb(UWORD8 task, UWORD8 param)
+ − {
+ − BOOL en_task;
+ − BOOL task_param;
+ − UWORD16 neigh_radio_freq;
+ − UWORD16 pwr_level;
+ − UWORD8 active_neigh_id;
+ − #if (L1_FF_MULTIBAND == 1)
+ − UWORD16 operative_radio_freq;
+ − #endif
+ −
+ −
+ − /*--------------------------------------------------------*/
+ − /* READ NEIGBOR CELL RECEIVE TASK RESULTS... */
+ − /*--------------------------------------------------------*/
+ − /* Rem: the full result is present in the mcu<-dsp */
+ − /* communication buffer. */
+ − /*--------------------------------------------------------*/
+ − // Get "enable" task flag and "synchro semaphore" for current task.
+ − en_task = l1a_l1s_com.l1s_en_task[task];
+ − task_param = l1a_l1s_com.task_param[task];
+ −
+ − if((en_task) && !(task_param))
+ − // Check the task semaphore and the task enable bit. The reading
+ − // task body is executed only when the task semaphore is 0 and the
+ − // task is still enabled.
+ − // The semaphore can be set to 1 whenever L1A makes some changes
+ − // to the task parameters. The task can be disabled by L1A.
+ − {
+ − // Traces and debug.
+ − // ******************
+ −
+ − #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+ − trace_fct(CST_L1S_READ_NNB ,(UWORD32)(-1));
+ − #endif
+ −
+ −
+ − #if (TRACE_TYPE!=0)
+ − // Check task identifier...
+ − #if L1_GPRS
+ − switch(l1a_l1s_com.dsp_scheduler_mode)
+ − {
+ − case GSM_SCHEDULER:
+ − {
+ − if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_d & 0xffff) != (UWORD32)DSP_TASK_CODE[task])
+ − trace_fct(CST_DL_TASKS_DO_NOT_CORRESPOND, (UWORD32)(-1));
+ − } break;
+ − case GPRS_SCHEDULER:
+ − {
+ − if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_md & 0xffff) != (UWORD32)DSP_TASK_CODE[task])
+ − trace_fct(CST_DL_TASKS_DO_NOT_CORRESPOND, (UWORD32)(-1));
+ − } break;
+ − }
+ − #else
+ − if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_d & 0xffff) != (UWORD32)DSP_TASK_CODE[task])
+ − trace_fct(CST_DL_TASKS_DO_NOT_CORRESPOND, (UWORD32)(-1));
+ − #endif
+ − #endif
+ −
+ − l1_check_com_mismatch(task);
+ −
+ − #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+ − uart_trace(task);
+ − #endif
+ −
+ − if(task == BCCHN)
+ − active_neigh_id = l1a_l1s_com.bcchn.active_neigh_id_norm;
+ − else // BCCHN_TRAN and BCCHN_TOP tasks
+ − active_neigh_id = l1a_l1s_com.bcchn.active_neigh_id_top;
+ −
+ − // the mean power level is impossible for the neighbor bloc, so the las input level is used.
+ − neigh_radio_freq = l1a_l1s_com.bcchn.list[active_neigh_id].radio_freq;
+ − #if 1 /* FreeCalypso TCS211 reconstruction */
+ − pwr_level = l1a_l1s_com.last_input_level[neigh_radio_freq].input_level;
+ − #elif (L1_FF_MULTIBAND == 0)
+ − pwr_level = l1a_l1s_com.last_input_level[neigh_radio_freq - l1_config.std.radio_freq_index_offset].input_level;
+ − #else
+ − operative_radio_freq = l1_multiband_radio_freq_convert_into_operative_radio_freq(neigh_radio_freq);
+ − pwr_level = l1a_l1s_com.last_input_level[operative_radio_freq].input_level;
+ − #endif
+ −
+ −
+ −
+ − // Read downlink DATA block from MCU/DSP interface.
+ − // *************************************************
+ −
+ − // Read L3 frame block and send msg to L1A.
+ − #if L1_GPRS
+ − if (l1a_l1s_com.dsp_scheduler_mode == GSM_SCHEDULER)
+ − l1s_read_l3frm(pwr_level,&(l1s_dsp_com.dsp_ndb_ptr->a_cd[0]), task);
+ − else
+ − l1s_read_l3frm(pwr_level,&(l1ps_dsp_com.pdsp_ndb_ptr->a_dd_gprs[0][0]), task);
+ − #else
+ − l1s_read_l3frm(pwr_level,&(l1s_dsp_com.dsp_ndb_ptr->a_cd[0]), task);
+ − #endif
+ − // Disable the served TC from the TC bitmap.
+ − if(task == BCCHN)
+ − l1a_l1s_com.bcchn.list[active_neigh_id].bcch_blks_req ^=
+ − ((UWORD16)(1L << l1a_l1s_com.bcchn.active_neigh_tc_norm));
+ − else // BCCHN_TRAN and BCCHN_TOP tasks
+ − l1a_l1s_com.bcchn.list[active_neigh_id].bcch_blks_req ^=
+ − ((UWORD16)(1L << l1a_l1s_com.bcchn.active_neigh_tc_top));
+ − }
+ −
+ − // The BCCHN task was enabled and could cancel a PTCCH burst
+ − // This incomplete PTCCH decoding block cause DSP troubles and so COM/PM errors
+ − // and then a recovery (seen with ULYSS) => in this case restart the PTCCH from the burst 0
+ − #if L1_GPRS
+ − if (task == BCCHN_TRAN)
+ − if(l1a_l1s_com.l1s_en_task[PTCCH] == TASK_ENABLED)
+ − if(l1pa_l1ps_com.transfer.ptcch.activity & PTCCH_DL) // a PTCCH DL task is running
+ − if ((l1s.actual_time.t2 >= 13) && (l1s.actual_time.t2 <= 18)) // only if the BCCHN remove a PTCCH activity
+ − {
+ − // Restart PTCCH DL task from the begining (i.e BURST 0).
+ − l1pa_l1ps_com.transfer.ptcch.activity ^= PTCCH_DL; // disable PTCCH_DL activity running
+ − l1pa_l1ps_com.transfer.ptcch.request_dl = TRUE; // restart PTCCH DL from the Burst0
+ − }
+ − #endif
+ −
+ − // Disactivate task.
+ − // ******************
+ −
+ − // End of task -> task must become INACTIVE.
+ − l1s.task_status[task].current_status = INACTIVE;
+ −
+ − #if (L1_DEBUG_IQ_DUMP == 1)
+ − l1ddsp_read_iq_dump(task);
+ − #endif
+ −
+ − // Flag the use of the MCU/DSP dual page read interface.
+ − // ******************************************************
+ −
+ − // Set flag used to change the read page at the end of "l1_synch".
+ − l1s_dsp_com.dsp_r_page_used = TRUE;
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_read_dedic_dl() */
+ − /*-------------------------------------------------------*/
+ − /* */
+ − /* Description: */
+ − /* ------------ */
+ − /* This function is a "COMPLEX" function used by the L1S */
+ − /* tasks: DDL,ADL,TCHTH,TCHTF,TCHA. */
+ − /* This function is the reading result function used for */
+ − /* dedicated mode. Here is a summary of the execution: */
+ − /* */
+ − /* - Traces and debug. */
+ − /* - Read control results and feed control algo. */
+ − /* - Read DL DATA block from MCU/DSP interface. */
+ − /* - Flag the use of the MCU/DSP dual page read */
+ − /* interface. */
+ − /* */
+ − /* Input parameters: */
+ − /* ----------------- */
+ − /* "task" */
+ − /* DDL, SDCCH DOWNLINK reading task. */
+ − /* ADL, SACCH DOWNLINK (associated with SDCCH)reading */
+ − /* task. */
+ − /* TCHTH, TCH channel task when dedicated/TCH Half rate*/
+ − /* TCHTF, TCH channel task when dedicated/TCH Full rate*/
+ − /* TCHA, Associated channel task when dedicated/TCH. */
+ − /* */
+ − /* "burst_id" (used only by DDL/ADL tasks). */
+ − /* BURST_1, 1st burst of the task. */
+ − /* BURST_2, 2nd burst of the task. */
+ − /* BURST_3, 3rd burst of the task. */
+ − /* BURST_4, 4th burst of the task. */
+ − /* */
+ − /* Input parameters from globals: */
+ − /* ------------------------------ */
+ − /* "l1a_l1s_com.task_param" */
+ − /* task semaphore bit register. Used to skip the body */
+ − /* of this function if L1A has changed or is changing */
+ − /* some of the task parameters. */
+ − /* */
+ − /* "l1a_l1s_com.l1s_en_task" */
+ − /* L1S task enable bit register. */
+ − /* */
+ − /* Modified parameters from globals: */
+ − /* --------------------------------- */
+ − /* "l1s.task_status[task].current_status" */
+ − /* current task status. It must be reset (INACTIVE) */
+ − /* when the task is completed. */
+ − /* -> disactivate task. */
+ − /* */
+ − /* "l1s_dsp_com.dsp_r_page_used" */
+ − /* Flag used by the function which closes L1S */
+ − /* execution ("l1s_end_manager()") to know if the */
+ − /* MCU/DSP read page must be switched. */
+ − /* -> Set to 1. */
+ − /* */
+ − /* Use of MCU/DSP interface: */
+ − /* ------------------------- */
+ − /* "l1s_dsp_com.dsp_ndb_ptr" */
+ − /* pointer to the non double buffered part (NDB) of */
+ − /* the MCU/DSP interface. This part is R/W for both */
+ − /* DSP and MCU. */
+ − /* */
+ − /* "l1s_dsp_com.dsp_db_r_ptr" */
+ − /* pointer to the double buffered part (DB) of the */
+ − /* MCU/DSP interface. This pointer points to the READ */
+ − /* page. */
+ − /* */
+ − /* RXQUAL : */
+ − /* 1) SDCCH : for RXQUAL_FULL and RXQUAL_SUB we accumu- */
+ − /* -late number of estimated errors (a_cd[2]) */
+ − /* for ALL SACCH and SDCCH TDMA frames. */
+ − /* 2) TCH : for RXQUAL_FULL in TCH_FS_MODE and */
+ − /* TCH_24F_MODE, we accumulate number of */
+ − /* estimated errors for ALL FACCH (a_fd[2]) */
+ − /* TDMA frames and ALL speech (a_dd_0[2]) */
+ − /* TDMA frames. */
+ − /* for RXQUAL_FULL in all data modes (except */
+ − /* TCH_24F_MODE, see above) we accumulate */
+ − /* number of errors for ALL FACCH (a_fd[2]) */
+ − /* TDMA frames and ALL data (a_dd_0[2]) */
+ − /* TDMA frames. */
+ − /* for RXQUAL_SUB in TCH_FS_MODE and */
+ − /* TCH_24F_MODE, we only accumulate number of */
+ − /* estimated errors for FACCH (a_fd[2]) TDMA */
+ − /* frames and speech (a_dd_0[2]) TDMA frames */
+ − /* at SID block boundary position. */
+ − /* for RXQUAL_SUB in all data modes (except */
+ − /* TCH_24F_MODE, see above) we only accumulate*/
+ − /* number of estimated errors for FACCH */
+ − /* (a_fd[2]) TDMA frames at SID block boundary*/
+ − /* position. The GSM specification 5.08 $8.4 */
+ − /* is not clear about data block at SID block */
+ − /* boundary position. Do we need to accumulate*/
+ − /* if L2/fill frame at this SID block boundary*/
+ − /* position. */
+ − /* Note: before accumulating FACCH TDMA frame we only */
+ − /* check b_blud value, we don't mind about b_fire. */
+ − /*-------------------------------------------------------*/
+ − void l1s_read_dedic_dl(UWORD8 task, UWORD8 burst_id)
+ − {
+ − UWORD32 toa;
+ − UWORD32 pm;
+ − UWORD32 angle;
+ − UWORD32 snr;
+ − BOOL beacon;
+ − T_INPUT_LEVEL *IL_info_ptr;
+ − UWORD16 radio_freq=0;
+ −
+ − #if TESTMODE
+ − UWORD32 pm_fullres =0;//omaps00090550
+ − #endif
+ −
+ −
+ − #if REL99
+ − #if FF_EMR
+ − T_EMR_PARAMS emr_params; // strucutre to store pre-calculated parameter
+ −
+ − /*--------------------------------------------------------*/
+ − /* INITIALIZATION OF EMR params.. */
+ − /*--------------------------------------------------------*/
+ −
+ − emr_params.task = task;
+ − emr_params.burst_id = burst_id;
+ − emr_params.facch_present = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_BLUD)) >> B_BLUD;
+ − emr_params.facch_fire1 = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_FIRE1)) >> B_FIRE1;
+ − emr_params.a_dd_0_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+ − emr_params.a_dd_0_bfi = ((l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0])&(1<<B_BFI)) >> B_BFI; // 3rd bit tells the BAD frame
+ − emr_params.a_dd_1_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & (1<<B_BLUD)) >> B_BLUD;
+ − emr_params.a_dd_1_bfi = ((l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0])&(1<<B_BFI)) >> B_BFI; // 3rd bit tells the BAD frame
+ − emr_params.b_m1 = ((l1s_dsp_com.dsp_ndb_ptr->a_data_buf_dl[1]) &(1<<B_M1)) >> B_M1; // = 1 if second half frame for data 14.4
+ − emr_params.b_f48blk_dl = ((l1s_dsp_com.dsp_ndb_ptr->d_ra_act) &(1<<B_F48BLK_DL)) >> B_F48BLK_DL; // = 1 if second half frame for data 4.8
+ − emr_params.b_ce = (((l1s_dsp_com.dsp_ndb_ptr->d_ra_conf) & (1<<B_CE)) >> B_CE);
+ − emr_params.a_ntd = (((l1s_dsp_com.dsp_ndb_ptr->a_data_buf_dl[1]) & (1<<B_FCS_OK)) >> B_FCS_OK);
+ − emr_params.a_cd_fire1 = (l1s_dsp_com.dsp_ndb_ptr->a_cd[0] & (1<<B_FIRE1)) >> B_FIRE1;
+ − emr_params.sid_present_sub0 = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_SID1)) >> B_SID1; // find out whether sid1 is 0/1
+ − emr_params.sid_present_sub1 = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & (1<<B_SID1)) >> B_SID1; // find out whether sid1 is 0/1
+ − #if (AMR == 1)
+ − emr_params.amr_facch_present= (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_BLUD)) >> B_BLUD;
+ − emr_params.amr_facch_fire1 = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_FIRE1)) >> B_FIRE1;
+ − emr_params.b_ratscch_blud = (l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0] & (1<<B_BLUD)) >> B_BLUD;
+ − emr_params.ratscch_rxtype = (l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+ − emr_params.amr_rx_type_sub0 = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+ − emr_params.amr_rx_type_sub1 = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+ − #endif //(AMR == 1)
+ − #endif //FF_EMR
+ − #endif //REL99
+ −
+ −
+ −
+ − /*--------------------------------------------------------*/
+ − /* READ DEDICATED CHANNEL DL RESULTS... */
+ − /*--------------------------------------------------------*/
+ −
+ − // Traces and debug.
+ − // ******************
+ − #if (TRACE_TYPE!=0) && (TRACE_TYPE !=5)
+ − trace_fct(CST_L1S_READ_DEDIC_DL, -1);
+ − #endif
+ −
+ − #if (TRACE_TYPE!=0)
+ − // Check task identifier...
+ − if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_d & 0xffff) != (UWORD32)DSP_TASK_CODE[task])
+ − trace_fct(CST_DL_TASKS_DO_NOT_CORRESPOND, (UWORD32)(-1));
+ − #endif
+ −
+ − #if (TESTMODE)
+ − // WARNING!
+ − // Don't trace MCU-DSP mismatches during UL-only in TestMode. The DSP is not working
+ − // in that case so it is normal. However, if tracing happens the CPU overloads
+ − if (l1_config.TestMode && l1_config.tmode.rf_params.down_up & TMODE_DOWNLINK)
+ − #endif
+ − {
+ − l1_check_com_mismatch(task);
+ − }
+ −
+ − radio_freq = l1a_l1s_com.dedic_set.radio_freq_dd;
+ −
+ − if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
+ − {
+ − beacon=1;
+ − IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas_beacon;
+ − }
+ − else
+ − {
+ − beacon=0;
+ − IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas;
+ − }
+ −
+ − #if (AMR == 1)
+ − {
+ − // RATSCCH detection
+ − UWORD16 ratscch_dl_header=l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0];
+ − UWORD16 b_ratscch_dl_blud = (ratscch_dl_header & (1<<B_BLUD)) >> B_BLUD;
+ −
+ − if(b_ratscch_dl_blud==TRUE)
+ − {
+ − UWORD8 rx_type = (ratscch_dl_header & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+ −
+ − if(rx_type==C_RATSCCH_GOOD)
+ − {
+ − // RATSCCH block detected
+ − l1s_amr_update_from_ratscch(&l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0]);
+ − }
+ − }
+ − }
+ − #endif // AMR
+ −
+ − switch(task)
+ − {
+ − case DDL :
+ − case ADL :
+ − /*---------------------------------------------------*/
+ − /* Dedicated mode: SDCCH receive task. */
+ − /* Rem: only a partial result is present in the */
+ − /* mcu<-dsp communication buffer. The BLOCK content */
+ − /* itself is in the last comm. (BURST_4) */
+ − /*---------------------------------------------------*/
+ − {
+ − UWORD8 i, IL_for_rxlev;
+ −
+ − #if (TRACE_TYPE!=0)
+ − // Check burst identifier...
+ − if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_burst_d & 0xffff) != burst_id)
+ − trace_fct(CST_DL_BURST_DOES_NOT_CORRESPOND, (UWORD32)(-1));
+ − #endif
+ −
+ − // Read control results and feed control algorithms.
+ − // **************************************************
+ −
+ − // Read control information.
+ − toa = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_TOA] & 0xffff;
+ − pm = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM] & 0xffff) >> 5;
+ − angle = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_ANGLE] & 0xffff;
+ − snr = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_SNR] & 0xffff;
+ −
+ − l1_check_pm_error(pm, task);
+ −
+ − // Update AGC: Call DPAGC algorithm
+ − IL_for_rxlev = l1ctl_dpagc(0,beacon,(UWORD8)pm,radio_freq,IL_info_ptr); // dtx_on = 0
+ −
+ − // Dedicated mode serving cell measurement reading.
+ − #if REL99
+ − #if FF_EMR
+ − // only task,burst_id is valid in structure pointed by *emr_params
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 1, &emr_params);
+ − #endif
+ − #else
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 1);
+ − #endif
+ −
+ − #if TRACE_TYPE==3
+ − stats_samples_nb(toa,pm,angle,snr,burst_id,task);
+ − #endif
+ −
+ − // Update AFC: Call AFC control function (KALMAN filter).
+ − #if AFC_ALGO
+ − #if TESTMODE
+ − if (l1_config.afc_enable)
+ − #endif
+ − {
+ − #if (VCXO_ALGO == 0)
+ − l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq);
+ − #else
+ − l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq,l1a_l1s_com.mode);
+ − #endif
+ − }
+ − #endif
+ −
+ − //Feed TOA histogram.
+ − #if (TOA_ALGO != 0)
+ − #if (TOA_ALGO == 2)
+ − if(l1s.toa_var.toa_snr_mask == 0)
+ − #else
+ − if(l1s.toa_snr_mask == 0)
+ − #endif
+ − {
+ − #if 1 /* FreeCalypso TCS211 reconstruction */
+ − if (IL_for_rxlev < IL_FOR_RXLEV_SNR)
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa, &l1s.toa_update, &l1s.toa_period_count);
+ − else
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa, &l1s.toa_update, &l1s.toa_period_count);
+ − #else
+ − UWORD32 snr_temp;
+ − snr_temp = (IL_for_rxlev < IL_FOR_RXLEV_SNR)? snr: 0;
+ − #if (TOA_ALGO == 2)
+ − l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa);
+ − #else
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa, &l1s.toa_update, &l1s.toa_period_count
+ − #if (FF_L1_FAST_DECODING ==1)
+ − ,0
+ − #endif
+ − );
+ − #endif
+ − #endif
+ − }
+ − #endif
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − RTTL1_FILL_DL_BURST(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev)
+ − #endif
+ − #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4)) && HAVE_L1_TRACE_BURST_PARAM
+ − l1_trace_burst_param(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev);
+ − #endif
+ − #if (BURST_PARAM_LOG_ENABLE == 1)
+ − l1_log_burst_param(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev);
+ − #endif
+ − // Read downlink DATA block from MCU/DSP interface.
+ − // *************************************************
+ −
+ − if(burst_id == BURST_4)
+ − {
+ − #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+ − uart_trace(task);
+ − #endif
+ −
+ − if(task == DDL)
+ − {
+ − // Read DCCH DL data block from DSP, pass it to L2.
+ − l1s_read_dcch_dl(l1s_dsp_com.dsp_ndb_ptr->a_cd, task);
+ − }
+ − else
+ − {
+ − // Read L2 frame block and send msg to L1A.
+ − l1s_read_sacch_dl(l1s_dsp_com.dsp_ndb_ptr->a_cd, task);
+ − }
+ −
+ − // RXQUAL_FULL/RXQUAL_SUB : number of estimated errors, this value is contained
+ − // in a_cd[2] field, for every SACCH and SDDCH blocks
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_cd[2]&0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += A_D_BLEN;
+ − l1a_l1s_com.Smeas_dedic.qual_acc_sub += l1s_dsp_com.dsp_ndb_ptr->a_cd[2]&0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += A_D_BLEN;
+ −
+ − // TEMPORARY : reset buffers and flags in NDB ...
+ − // reset nerr....
+ − // reset A_CD contents.......
+ − l1s_dsp_com.dsp_ndb_ptr->a_cd[0] = (1<<B_FIRE1); // B_FIRE1=1,B_FIRE0=0,BLUD=0.
+ − l1s_dsp_com.dsp_ndb_ptr->a_cd[2] = 0xffff;
+ − for (i=0; i<12 ;i++)
+ − l1s_dsp_com.dsp_ndb_ptr->a_cd[3+i] = 0x0000;
+ −
+ − // task is completed, make it INACTIVE.
+ − l1s.task_status[task].current_status = INACTIVE;
+ − }
+ − }
+ − break;
+ −
+ − case TCHTH:
+ − /*---------------------------------------------------*/
+ − /* Dedicated mode: TCHTH receive task. */
+ − /* HALF RATE */
+ − /*---------------------------------------------------*/
+ − {
+ − UWORD32 b_blud;
+ − UWORD8 channel_mode;
+ − //OMAPS00090550 UWORD8 channel_type;
+ − UWORD8 subchannel;
+ − UWORD32 l1_mode;
+ − UWORD32 fn_mod_104;
+ − UWORD32 fn_mod_52;
+ − //OMAPS00090550 UWORD32 fn_report_mod13_mod4;
+ − UWORD32 normalised_fn_report_mod13_mod4;
+ − UWORD32 normalised_fn_report_mod26;
+ − UWORD8 IL_for_rxlev = 0; //omaps00090550
+ − #if (AMR == 1)
+ − UWORD8 rx_type;
+ − UWORD8 b_ratscch_blud,b_facch_blud;
+ − UWORD8 voco_type;
+ − BOOL facch_present = FALSE;
+ − #if REL99
+ − #if FF_EMR
+ − emr_params.amr_facch_present = FALSE;
+ − emr_params.amr_facch_fire1 = FALSE;
+ − #endif
+ − #endif
+ − #endif
+ −
+ − // Read control results and feed control algorithms.
+ − // **************************************************
+ −
+ − // Read control information.
+ − toa = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_TOA] & 0xffff;
+ − pm = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM] & 0xffff) >> 5;
+ − angle = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_ANGLE] & 0xffff;
+ − snr = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_SNR] & 0xffff;
+ −
+ − l1_check_pm_error(pm, task);
+ −
+ − #if TRACE_TYPE==3
+ − stats_samples_tch(toa,pm,angle,snr);
+ − #endif
+ − #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+ − uart_trace(TCHTH);
+ − #endif
+ −
+ − // Update AFC: Call AFC control function (KALMAN filter).
+ −
+ − #if AFC_ALGO
+ − #if TESTMODE
+ − if (l1_config.afc_enable)
+ − #endif
+ − {
+ − #if (VCXO_ALGO == 0)
+ − l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq);
+ − #else
+ − l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq,l1a_l1s_com.mode);
+ − #endif
+ − }
+ − #endif
+ −
+ − // Increment number of burst not sent due to DTX.
+ − if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_u & 0xffff) == TCH_DTX_UL)
+ − {
+ − l1a_l1s_com.Smeas_dedic.dtx_used++;
+ − l1s.dtx_ul_on = TRUE;
+ − }
+ − else
+ − {
+ − l1s.dtx_ul_on = FALSE;
+ − }
+ −
+ − // Check SID frame subset...
+ − channel_mode = l1a_l1s_com.dedic_set.aset->achan_ptr->mode;
+ − //OMAPS00090550 channel_type = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type;
+ − subchannel = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->subchannel;
+ − fn_mod_104 = l1s.actual_time.fn % 104;
+ − fn_mod_52 = l1s.actual_time.fn % 52;
+ −
+ − #if REL99
+ − #if FF_EMR
+ − // Compute FN in reporting period % 13 % 4 = (((FN-subchannel)+ 13) %13) %4
+ − normalised_fn_report_mod13_mod4 = ((l1s.actual_time.fn - subchannel + 13) % 13) % 4;
+ −
+ − // Compute FN in reporting period % 26 independently of the considered subchannel.
+ − normalised_fn_report_mod26 = (l1s.actual_time.fn - subchannel + 26) % 26;
+ −
+ − emr_params.channel_mode = channel_mode;
+ − emr_params.subchannel = subchannel;
+ − emr_params.normalised_fn_mod13_mod4 = normalised_fn_report_mod13_mod4;
+ − #endif //FF_EMR
+ − #endif //REL99
+ −
+ −
+ − #if (AMR == 1)
+ − // Check if we're in AMR DTX mode
+ − if(channel_mode==TCH_AHS_MODE &&
+ − ( (((l1s.actual_time.fn_mod13 % 4)==3) && (subchannel==0)) || // AHS0: block is decoded on DSP side at fn%13%4=2
+ − (((l1s.actual_time.fn_mod13 % 4)==0) && (subchannel==1)) )) // AHS1: block is decoded on DSP side at fn%13%4=3
+ − {
+ − if(subchannel==0)
+ − {
+ − b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+ − rx_type = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+ − }
+ − else
+ − {
+ − b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & (1<<B_BLUD)) >> B_BLUD;
+ − rx_type = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+ − }
+ − b_ratscch_blud = (l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0] & (1<<B_BLUD)) >> B_BLUD;
+ − b_facch_blud = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_BLUD)) >> B_BLUD;
+ −
+ − // Check if AMR DTX mode is on
+ − if((((rx_type==SID_FIRST) || (rx_type==SID_UPDATE) || (rx_type==SID_BAD)) && b_blud==TRUE) ||
+ − (rx_type==AMR_NO_DATA && b_blud==FALSE))
+ − {
+ − l1s.dtx_amr_dl_on=TRUE;
+ − }
+ − else if(b_ratscch_blud==FALSE && b_facch_blud==FALSE)
+ − {
+ − l1s.dtx_amr_dl_on=FALSE;
+ − }
+ − }
+ − #endif
+ −
+ − #if (AMR == 1)
+ − if (channel_mode != TCH_AHS_MODE)
+ − {
+ − // This AGC and TOA update isn't applied to the adaptative half rate mode.
+ − if(((channel_mode == TCH_HS_MODE) && (subchannel == 0) &&
+ − (fn_mod_52 > 0) && (fn_mod_52 <= 7)) ||
+ − ((channel_mode == TCH_HS_MODE) && (subchannel == 1) &&
+ − (fn_mod_52 > 14) && (fn_mod_52 <= 21)) ||
+ − ((channel_mode != TCH_HS_MODE) &&
+ − (subchannel == 0) && (fn_mod_104 > 56) && (fn_mod_104 <= 76)) ||
+ − ((channel_mode != TCH_HS_MODE) &&
+ − (subchannel == 1) && (fn_mod_104 > 66) && (fn_mod_104 <= 86)))
+ − #else
+ − if(((channel_mode == TCH_HS_MODE) && (subchannel == 0) &&
+ − (fn_mod_52 > 0) && (fn_mod_52 <= 7)) ||
+ − ((channel_mode == TCH_HS_MODE) && (subchannel == 1) &&
+ − (fn_mod_52 > 14) && (fn_mod_52 <= 21)) ||
+ − ((channel_mode != TCH_HS_MODE) && (subchannel == 0) &&
+ − (fn_mod_104 > 56) && (fn_mod_104 <= 76)) ||
+ − ((channel_mode != TCH_HS_MODE) && (subchannel == 1) &&
+ − (fn_mod_104 > 66) && (fn_mod_104 <= 86)))
+ − #endif
+ − // Current results are from the TDMA frame subset always received (GSM05.08, $8.3).
+ − // -> pwr meas. must be used for SUB set result.
+ − // -> TOA filtering can be fed with SNR/TOA.
+ − // WARNING: TCH/H in signalling only is here processed like TCH/H data. GSM spec is
+ − // ======== unclear !!!!!!!!!!!!!!!1
+ − {
+ − // Update AGC: Call DPAGC algorithm
+ − IL_for_rxlev = l1ctl_dpagc(1,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+ −
+ − // Dedicated mode serving cell measurement reading, indicate "SUB".
+ − #if REL99
+ − #if FF_EMR
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 1,&emr_params);
+ − #endif
+ − #else
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 1);
+ − #endif
+ −
+ − //Feed TOA histogram.
+ − #if (TOA_ALGO != 0)
+ − // When in 1/2 rate data, we are working on 14 SID frames (instead
+ − // of 12 otherwise), so we need to increment length of the histogram
+ − // filling period from 36 to 42.
+ − if (channel_mode != TCH_HS_MODE)
+ − l1_mode=DEDIC_MODE_HALF_DATA;
+ − else
+ − l1_mode=l1a_l1s_com.mode;
+ −
+ − #if (TOA_ALGO == 2)
+ − if(l1s.toa_var.toa_snr_mask == 0)
+ − #else
+ − if(l1s.toa_snr_mask == 0)
+ − #endif
+ − {
+ − #if 1 /* FreeCalypso TCS211 reconstruction */
+ − if (IL_for_rxlev < IL_FOR_RXLEV_SNR)
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1_mode, snr, toa, &l1s.toa_update, &l1s.toa_period_count);
+ − else
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1_mode, 0, toa, &l1s.toa_update, &l1s.toa_period_count);
+ − #else
+ − UWORD32 snr_temp;
+ − snr_temp = (IL_for_rxlev < IL_FOR_RXLEV_SNR)? snr: 0;
+ − #if (TOA_ALGO == 2)
+ − l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1_mode, snr_temp, toa);
+ − #else
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1_mode, snr_temp, toa, &l1s.toa_update, &l1s.toa_period_count
+ − #if (FF_L1_FAST_DECODING == 1)
+ − ,0
+ − #endif
+ − );
+ − #endif
+ − #endif
+ − }
+ − #endif
+ − } // if(((channel_mode == TCH_HS_MODE) && (subchannel == 0) &&
+ − else
+ − {
+ − // Update AGC: Call DPAGC algorithm
+ − IL_for_rxlev = l1ctl_dpagc(0,beacon,(UWORD8)pm,radio_freq,IL_info_ptr);
+ −
+ − // Dedicated mode serving cell measurement reading, full set only.
+ − #if REL99
+ − #if FF_EMR
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+ − #endif
+ − #else
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+ − #endif
+ − }
+ −
+ − #if (AMR == 1)
+ − } // if (channel_mode != TCH_AHS_MODE)
+ − #endif
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − RTTL1_FILL_DL_BURST(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev)
+ − #endif
+ − #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4)) && HAVE_L1_TRACE_BURST_PARAM
+ − l1_trace_burst_param(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev);
+ − #endif
+ − #if (BURST_PARAM_LOG_ENABLE == 1)
+ − l1_log_burst_param(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev);
+ − #endif
+ −
+ − // Read downlink DATA block from MCU/DSP interface.
+ − // *************************************************
+ −
+ − // Compute FN % 13 % 4
+ − //OMAPS00090550 fn_report_mod13_mod4 = (l1s.actual_time.fn_mod13) % 4;
+ − // Compute normalised FN % 13 %4 = (((FN-subchannel)+ 13) %13) %4
+ − normalised_fn_report_mod13_mod4 = ((l1s.actual_time.fn - subchannel + 13) % 13) % 4;
+ − // Compute normalised FN %26 = ((FN - subchannel)+ 26) %26
+ − normalised_fn_report_mod26 = (l1s.actual_time.fn - subchannel + 26) % 26;
+ −
+ − if((normalised_fn_report_mod26 == 16)||
+ − (normalised_fn_report_mod26 == 24)||
+ − (normalised_fn_report_mod26 == 7))
+ − // It is time to get FACCH/H data block.
+ − {
+ − // FACCH: Check A_FD information block.
+ − //-------------------------------------
+ −
+ − UWORD8 temp;
+ − b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_BLUD)) >> B_BLUD;
+ − #if ((REL99) && (AMR == 1))
+ − #if FF_EMR
+ − emr_params.amr_facch_fire1 = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_FIRE1)) >> B_FIRE1;
+ − #endif
+ − #endif
+ −
+ − if(b_blud == TRUE)
+ − {
+ − // Read FACCH DL data block from DSP, pass it to L2.
+ − #if ( FF_REPEATED_DL_FACCH == 1 )
+ − #if (TRACE_TYPE == 1 || TRACE_TYPE == 4)
+ − trace_info.facch_dl_count_all++;
+ − #endif
+ − // if the current block is a repetition reports NULL to L2 otherwise reports the current block
+ − l1s_read_dcch_dl((API*)l1s_repeated_facch_check(l1s_dsp_com.dsp_ndb_ptr->a_fd), task);
+ − #else
+ − l1s_read_dcch_dl(l1s_dsp_com.dsp_ndb_ptr->a_fd, task);
+ − #endif
+ −
+ − #if (AMR == 1)
+ − if (channel_mode != TCH_AHS_MODE)
+ − {
+ − #endif
+ −
+ − // RXQUAL_SUB : In case of data taffic channels, accumulate number of
+ − // estimated errors, this value is contained in a_fd[2] field, only
+ − // for SID TDMA frames received as FACCH frames. (GSM 5.08 $8.4)
+ − if (((fn_mod_104==59) && (channel_mode==TCH_HS_MODE) && (subchannel==0)) ||
+ − ((fn_mod_104==73) && (channel_mode==TCH_HS_MODE) && (subchannel==1)) ||
+ − ((fn_mod_104==76) && ((channel_mode==TCH_48H_MODE)||
+ − (channel_mode==TCH_24H_MODE)) && (subchannel==0)) ||
+ − ((fn_mod_104==86) && ((channel_mode==TCH_48H_MODE)||
+ − (channel_mode==TCH_24H_MODE)) && (subchannel==1)))
+ − // last SID TDMA frame received as FACCH frames.
+ − {
+ − l1a_l1s_com.Smeas_dedic.qual_acc_sub += l1s_dsp_com.dsp_ndb_ptr->a_fd[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += TCH_F_D_BLEN;
+ − }
+ −
+ − #if (AMR == 1)
+ − } // if (channel_mode != TCH_AHS_MODE)
+ − else
+ − {
+ − // Indicate to AMR specific processing that burst was a FACCH
+ − facch_present = TRUE;
+ − #if ((REL99) && (AMR == 1))
+ − #if FF_EMR
+ − emr_params.amr_facch_present = facch_present;
+ − #endif
+ − #endif
+ −
+ −
+ − // Update AGC: Call DPAGC algorithm
+ − IL_for_rxlev = l1ctl_dpagc_amr(0,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+ −
+ − // Dedicated mode serving cell measurement reading, indicate "FULL".
+ − #if REL99
+ − #if FF_EMR
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+ − #endif
+ − #else
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+ − #endif
+ − }
+ − #endif
+ −
+ − // RXQUAL_FULL : accumulate number of estimated errors, this value is
+ − // contained in a_fd[2] field, for each TCHT block.
+ − // The same for AMR
+ − #if (AMR == 1)
+ − // in AMR, l1s.dtx_amr_dl_on is FALSE if DTX mode is off
+ − // in non AMR TCH, l1s.dtx_amr_dl_on is always FALSE
+ − // In AMR DTX, DSP patch sometimes reports FACCH blocks which ARE NOT FACCH blocks
+ − // therefore they shouldn't be taken into account in the RXQUALL_FULL computation
+ − if(l1s.dtx_amr_dl_on==FALSE)
+ − #endif
+ − {
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_fd[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_F_D_BLEN;
+ − }
+ −
+ − // Reset A_FD header.
+ − // B_FIRE1 =1, B_FIRE0 =0 , BLUD =0
+ − l1s_dsp_com.dsp_ndb_ptr->a_fd[0] = (1<<B_FIRE1);
+ − l1s_dsp_com.dsp_ndb_ptr->a_fd[2] = 0xffff;
+ −
+ − // Rem: when FACCH is received, we must reset A_DD_0 header also.
+ − // Reset A_DD_0 header in NDB.
+ − #if (AMR == 1)
+ − if ((channel_mode==TCH_AHS_MODE) && (subchannel==0))
+ − {
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] &= (API)(RX_TYPE_MASK);
+ − }
+ − else
+ − #endif
+ − {
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] = 0;
+ − }
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+ −
+ − // Rem: when FACCH is received, we must reset A_DD_1 header also.
+ − // Reset A_DD_0 header in NDB.
+ − #if (AMR == 1)
+ − if ((channel_mode==TCH_AHS_MODE) && (subchannel==1))
+ − {
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] &= (API)(RX_TYPE_MASK);
+ − }
+ − else
+ − #endif
+ − {
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] = 0;
+ − }
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] = 0xffff;
+ −
+ − } // if(b_blud == TRUE)
+ −
+ − else
+ − // No FACCH received at FACCH boundary frame. Nevertheless, need to read dummy
+ − // FACCH DL data block.
+ − {
+ − // Dummy: Read FACCH DL data block from DSP, pass it to L2.
+ − // Rem: this is an upper layer requirement to call this
+ − // function at every FACCH DL boundary.
+ − l1s_read_dcch_dl(NULL, task);
+ − }
+ − } // if((normalised_fn_report_mod26 == 16)|| ...
+ −
+ − // else we are not at FACCH boundary frame
+ − // We must check for the presence of a TCH/H block (even if it does fall on a FACCH boundary)
+ − // We use the b_blud bit to confirm presence of TCH/H (or FACCH)
+ − if((normalised_fn_report_mod13_mod4 == 3) && (channel_mode==TCH_HS_MODE))
+ − // It is time to get TCH/HS data block.
+ − {
+ − #if TRACE_TYPE==3
+ − if (l1_stats.type == PLAY_UL &&
+ − (channel_mode == TCH_HS_MODE))
+ − play_trace();
+ − #endif
+ −
+ − // Check A_DD_0 information block only if no FACCH.
+ − if (subchannel==0)
+ − b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+ − else
+ − b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & (1<<B_BLUD)) >> B_BLUD;
+ −
+ − if(b_blud == TRUE)
+ − {
+ − if (subchannel==0)
+ − {
+ − // RXQUAL_SUB : In case of speech traffic channels, accumulate number of
+ − // estimated errors, this value is contained in a_dd_0[2] field, only
+ − // for SID TDMA frames. (GSM 5.08 $8.4)
+ − if (fn_mod_104==59)
+ − {
+ − l1a_l1s_com.Smeas_dedic.qual_acc_sub += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += TCH_HS_BLEN;
+ − }
+ − // RXQUAL_FULL : accumulate number of estimated errors, this value is
+ − // contained in a_dd_0[2] field, for each TCHT block.
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+ − // Reset A_DD_0 header in NDB.
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] = 0;
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+ − } // if (subchannel==0)
+ − else
+ − {
+ − // RXQUAL_SUB : In case of speech traffic channels, accumulate number of
+ − // estimated errors, this value is contained in a_dd_1[2] field, only
+ − // for SID TDMA frames. (GSM 5.08 $8.4)
+ − if (fn_mod_104==73)
+ − {
+ − l1a_l1s_com.Smeas_dedic.qual_acc_sub += l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += TCH_HS_BLEN;
+ − }
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] & 0xffff;
+ − // Reset A_DD_1 header in NDB.
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] = 0;
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] = 0xffff;
+ − }
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_HS_BLEN;
+ − } // if(b_blud == TRUE)
+ − } // if((normalised_fn_report_mod13_mod4 == 3) && (channel_mode==TCH_HS_MODE))
+ −
+ − #if (AMR == 1)
+ − if(((normalised_fn_report_mod26 == 20) ||
+ − (normalised_fn_report_mod26 == 3) ||
+ − (normalised_fn_report_mod26 == 11)) &&
+ − ((channel_mode == TCH_48H_MODE) ||
+ − (channel_mode == TCH_24H_MODE)))
+ − #else
+ − if(((normalised_fn_report_mod26 == 20) ||
+ − (normalised_fn_report_mod26 == 3) ||
+ − (normalised_fn_report_mod26 == 11)) && (channel_mode!=TCH_HS_MODE))
+ − #endif
+ − // It is time to get TCH/H4.8 or TCH/H2.4 data block.
+ − {
+ − // Check A_DD_0 information block only if no FACCH.
+ − if (subchannel==0)
+ − b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+ − else
+ − b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & (1<<B_BLUD)) >> B_BLUD;
+ −
+ − if(b_blud == TRUE)
+ − {
+ − if (subchannel==0)
+ − {
+ − // RXQUAL_SUB : In case of speech traffic channels, accumulate number of
+ − // estimated errors, this value is contained in a_dd_0[2] field, only
+ − // for SID TDMA frames. (GSM 5.08 $8.4)
+ − if (fn_mod_104==76)
+ − {
+ − l1a_l1s_com.Smeas_dedic.qual_acc_sub += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += TCH_F_D_BLEN;
+ − }
+ − // RXQUAL_FULL : accumulate number of estimated errors, this value is
+ − // contained in a_dd_0[2] field, for each TCHT block.
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+ −
+ − // Reset A_DD_0 header in NDB.
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] = 0;
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+ − }
+ − else
+ − {
+ − // RXQUAL_SUB : In case of speech traffic channels, accumulate number of
+ − // estimated errors, this value is contained in a_dd_1[2] field, only
+ − // for SID TDMA frames. (GSM 5.08 $8.4)
+ − if (fn_mod_104==86)
+ − {
+ − l1a_l1s_com.Smeas_dedic.qual_acc_sub += l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += TCH_F_D_BLEN;
+ − }
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] & 0xffff;
+ − // Reset A_DD_1 header in NDB.
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] = 0;
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] = 0xffff;
+ − }
+ − // RXQUAL_FULL : accumulate number of estimated errors, this value is
+ − // contained in a_dd_1[2] field, for each TCHT block.
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_F_D_BLEN;
+ −
+ − // WARNING: sequence number is not implemented in DATA half rate
+ − // TO BE DEFINED......
+ − } // if(b_blud == TRUE)
+ − } // if(((normalised_fn_report_mod26 == 20) || ...
+ − #if (AMR == 1)
+ − if ((channel_mode == TCH_AHS_MODE) && (facch_present == FALSE))
+ − {
+ − // the channel is a TCH/AHS and it's time to receive a new block
+ − if (subchannel == 0)
+ − {
+ − // Load the bit to check if the block is valid
+ − b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+ − }
+ − else // subchannel 1
+ − {
+ − // Load the bit to check if the block is valid
+ − b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & (1<<B_BLUD)) >> B_BLUD;
+ − }
+ −
+ − b_ratscch_blud = (l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0] & (1<<B_BLUD)) >> B_BLUD;
+ −
+ − // All frames except NO_DATA (b_blud = FALSE) and FACCH, i.e AMR speech/SID block or a RATSCCH block
+ − if(b_ratscch_blud==TRUE)
+ − {
+ − // RXQUAL_FULL : accumulate number of estimated errors, this value is
+ − // contained in a_ratscch_dl[2] field, for each TCHT block.
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[2] & 0xffff;
+ −
+ − // Reset the A_RATSCCH_DL header in NDB.
+ − l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0] = 0;
+ − l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[2] = 0xffff;
+ −
+ − // RXQUAL_FULL : the number of bits examined for errors on serving cell depends on
+ − // the block received.
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += RATSCCH_BLEN;
+ −
+ − IL_for_rxlev = l1ctl_dpagc_amr(0,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+ − #if REL99
+ − #if FF_EMR
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+ − #endif
+ − #else
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+ − #endif
+ − }
+ − else if(b_blud==TRUE)
+ − {
+ − if (subchannel == 0)
+ − {
+ − // Load the type of the block received
+ − rx_type = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+ −
+ − // Load the type of vocoder currently used
+ − voco_type = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & VOCODER_TYPE_MASK) >> VOCODER_TYPE_SHIFT;
+ −
+ − #if (DEBUG_DEDIC_TCH_BLOCK_STAT == 1)
+ − Trace_dedic_tch_block_stat(rx_type, l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2], voco_type);
+ − #endif
+ −
+ − // RXQUAL_SUB : In case of adaptative traffic channel, accumulate number of estimated errors
+ − // is contained in the a_dd_0[2] value but the accumulation is made with SID_UPDATE frame only.
+ − if((rx_type==SID_UPDATE) || (rx_type==SID_BAD))
+ −
+ − {
+ − l1a_l1s_com.Smeas_dedic.qual_acc_sub += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += SID_UPDATE_BLEN;
+ − }
+ −
+ − // RXQUAL_FULL : accumulate number of estimated errors, this value is
+ − // contained in a_dd_0[2] field, for each TCHT block.
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+ −
+ −
+ −
+ −
+ −
+ −
+ −
+ −
+ −
+ − // Reset A_DD_0 header in NDB.
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] &= (API)(RX_TYPE_MASK);
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+ − }
+ − else // subchannel ==1
+ − {
+ − // Load the type of the block received
+ − rx_type = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+ −
+ − // Load the type of vocoder currently used
+ − voco_type = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & VOCODER_TYPE_MASK) >> VOCODER_TYPE_SHIFT;
+ −
+ − #if (DEBUG_DEDIC_TCH_BLOCK_STAT == 1)
+ − Trace_dedic_tch_block_stat(rx_type, l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2], voco_type);
+ − #endif
+ −
+ − // RXQUAL_SUB : In case of adaptative traffic channel, accumulate number of estimated errors
+ − // is contained in the a_dd_1[2] value but the accumulation is made with SID_UPDATE block only.
+ − if((rx_type==SID_UPDATE) || (rx_type==SID_BAD))
+ −
+ − {
+ − l1a_l1s_com.Smeas_dedic.qual_acc_sub += l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += SID_UPDATE_BLEN;
+ − }
+ −
+ − // RXQUAL_FULL : accumulate number of estimated errors, this value is
+ − // contained in a_dd_1[2] field, for each TCHT block.
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] & 0xffff;
+ −
+ − // Reset A_DD_1 header in NDB.
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] &= (API)(RX_TYPE_MASK);
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] = 0xffff;
+ − } // subchannel == 1
+ −
+ −
+ −
+ −
+ −
+ − // RXQUAL_FULL : the number of bits examined for errors on serving cell depends on
+ − // the block received.
+ − if((rx_type==SPEECH_GOOD) || (rx_type==SPEECH_DEGRADED) || (rx_type==SPEECH_BAD))
+ − {
+ − // The block length depens on the vocoder type
+ − switch (voco_type)
+ − {
+ − case AMR_CHANNEL_7_95:
+ − {
+ − // TCH-AHS 7.95
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AHS_7_95_BLEN;
+ − }
+ − break;
+ − case AMR_CHANNEL_7_4:
+ − {
+ − // TCH-AHS 7.4
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AHS_7_4_BLEN;
+ − }
+ − break;
+ − case AMR_CHANNEL_6_7:
+ − {
+ − // TCH-AHS 6.7
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AHS_6_7_BLEN;
+ − }
+ − break;
+ − case AMR_CHANNEL_5_9:
+ − {
+ − // TCH-AHS 5.9
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AHS_5_9_BLEN;
+ − }
+ − break;
+ − case AMR_CHANNEL_5_15:
+ − {
+ − // TCH-AHS 5.15
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AHS_5_15_BLEN;
+ − }
+ − break;
+ − case AMR_CHANNEL_4_75:
+ − {
+ − // TCH-AHS 4.75
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AHS_4_75_BLEN;
+ − }
+ − break;
+ − } // switch
+ − } // if ( (rx_type == SPEECH_GOOD) || ...
+ − else
+ − if((rx_type == SID_UPDATE) || (rx_type == SID_BAD))
+ −
+ − {
+ − // the block is a SID UPDATE
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += SID_UPDATE_BLEN;
+ − }
+ −
+ −
+ −
+ −
+ −
+ −
+ −
+ − // AGC, TOA update for AMR... SUB FIFO only for SID_UPDATE frame
+ − if((rx_type == SID_UPDATE) || (rx_type == SID_BAD))
+ −
+ − {
+ − IL_for_rxlev = l1ctl_dpagc_amr(1,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+ − #if REL99
+ − #if FF_EMR
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 1, &emr_params);
+ − #endif
+ − #else
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 1);
+ − #endif
+ −
+ − #if (TOA_ALGO != 0)
+ − #if (TOA_ALGO == 2)
+ − if(l1s.toa_var.toa_snr_mask == 0)
+ − #else
+ − if(l1s.toa_snr_mask == 0)
+ − #endif
+ − {
+ − #if 1 /* FreeCalypso TCS211 reconstruction */
+ − if (IL_for_rxlev < IL_FOR_RXLEV_SNR)
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa, &l1s.toa_update, &l1s.toa_period_count);
+ − else
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa, &l1s.toa_update, &l1s.toa_period_count);
+ − #else
+ − UWORD32 snr_temp;
+ − snr_temp = (IL_for_rxlev < IL_FOR_RXLEV_SNR)? snr: 0;
+ − #if (TOA_ALGO == 2)
+ − l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa);
+ − #else
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa, &l1s.toa_update, &l1s.toa_period_count
+ − #if (FF_L1_FAST_DECODING == 1)
+ − ,0
+ − #endif
+ − );
+ − #endif
+ − #endif
+ − }
+ − #endif
+ − }
+ − else
+ − {
+ − IL_for_rxlev = l1ctl_dpagc_amr(0,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+ − #if REL99
+ − #if FF_EMR
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+ − #endif
+ − #else
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+ − #endif
+ − }
+ − } // if (b_blud == TRUE)
+ − // simple burst or NO_DATA frame
+ − else
+ − {
+ − // NO_DATA is considered a bad frame
+ − if (normalised_fn_report_mod13_mod4 == 3)
+ − {
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AHS_4_75_BLEN;
+ − if (subchannel == 0)
+ − {
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+ −
+ − #if (DEBUG_DEDIC_TCH_BLOCK_STAT == 1)
+ − Trace_dedic_tch_block_stat(AMR_NO_DATA, l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2], 0);
+ − #endif
+ −
+ − // Reset A_DD_0 header in NDB.
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] &= (API)(RX_TYPE_MASK);
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+ − }
+ − else
+ − {
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] & 0xffff;
+ −
+ − #if (DEBUG_DEDIC_TCH_BLOCK_STAT == 1)
+ − Trace_dedic_tch_block_stat(AMR_NO_DATA, l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2], 0);
+ − #endif
+ −
+ − // Reset A_DD_0 header in NDB.
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] &= (API)(RX_TYPE_MASK);
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] = 0xffff;
+ − }
+ − }
+ − // Update AGC: Call DPAGC AMR algorithm in order to fill the G_all buffer
+ − IL_for_rxlev = l1ctl_dpagc_amr(0,beacon,(UWORD8)pm,radio_freq,IL_info_ptr);
+ −
+ − // Dedicated mode serving cell measurement reading, full set only.
+ − #if REL99
+ − #if FF_EMR
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+ − #endif
+ − #else
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+ − #endif
+ − }
+ − } // if ((channel_mode == TCH_AHS_MODE) && (facch_present == FALSE))
+ − #endif
+ −
+ − // task is completed, make it INACTIVE.
+ − l1s.task_status[task].current_status = INACTIVE;
+ − }
+ − break;
+ −
+ − case TCHTF:
+ − /*---------------------------------------------------*/
+ − /* Dedicated mode: TCHTF receive task. */
+ − /* FULL RATE */
+ − /*---------------------------------------------------*/
+ − {
+ − UWORD8 IL_for_rxlev = 0; //omaps00090550
+ − UWORD32 b_blud;
+ −
+ − UWORD8 channel_mode;
+ − //OMAPS00090550 UWORD8 channel_type;
+ − UWORD32 fn_mod_104;
+ − //OMAPS00090550 UWORD32 fn_mod_52;
+ − UWORD32 fn_report_mod13_mod4;
+ − #if (AMR == 1)
+ − UWORD8 rx_type;
+ − UWORD8 b_ratscch_blud,b_facch_blud;
+ − BOOL facch_present = FALSE;
+ − #endif
+ −
+ − #if TESTMODE
+ − xSignalHeaderRec *msg;
+ − #endif
+ −
+ − // Read control results and feed control algorithms.
+ − // **************************************************
+ −
+ − // Read control information.
+ − toa = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_TOA] & 0xffff;
+ − pm = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM] & 0xffff) >> 5;
+ − angle = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_ANGLE] & 0xffff;
+ − snr = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_SNR] & 0xffff;
+ −
+ − l1_check_pm_error(pm, task);
+ −
+ − #if TRACE_TYPE==3
+ − stats_samples_tch(toa,pm,angle,snr);
+ − #endif
+ −
+ − #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+ − uart_trace(TCHTF);
+ − #endif
+ −
+ − // Update AFC: Call AFC control function (KALMAN filter).
+ − #if AFC_ALGO
+ − #if TESTMODE
+ − if (l1_config.afc_enable)
+ − #endif
+ − {
+ − #if (VCXO_ALGO == 0)
+ − l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq);
+ − #else
+ − l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq,l1a_l1s_com.mode);
+ − #endif
+ − }
+ − #endif
+ −
+ − // Check SID frame subset...
+ − channel_mode = l1a_l1s_com.dedic_set.aset->achan_ptr->mode;
+ − //OMAPS00090550 channel_type = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type;
+ − fn_mod_104 = l1s.actual_time.fn % 104;
+ − //OMAPS00090550 fn_mod_52 = l1s.actual_time.fn % 52;
+ −
+ − #if (AMR == 1)
+ − // Check if we're in AMR DTX mode
+ − if(channel_mode==TCH_AFS_MODE && (l1s.actual_time.fn_mod13 % 4)==0) // AFS: block is decoded on DSP side at fn%13%4=3
+ − {
+ − b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+ − rx_type = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+ − b_ratscch_blud = (l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0] & (1<<B_BLUD)) >> B_BLUD;
+ − b_facch_blud = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_BLUD)) >> B_BLUD;
+ −
+ − // Check if AMR DTX mode is on
+ − if((((rx_type==SID_FIRST) || (rx_type==SID_UPDATE) || (rx_type==SID_BAD)) && b_blud==TRUE) ||
+ − (rx_type==AMR_NO_DATA && b_blud==FALSE))
+ − {
+ − l1s.dtx_amr_dl_on=TRUE;
+ − }
+ − else if(b_ratscch_blud==FALSE && b_facch_blud==FALSE)
+ − {
+ − l1s.dtx_amr_dl_on=FALSE;
+ − }
+ − }
+ − #endif
+ −
+ − #if REL99
+ − #if FF_EMR
+ − emr_params.channel_mode = channel_mode;
+ − // emr_params.fn_mod13_mod4 = l1s.actual_time.fn_mod13_mod4;
+ − #if (AMR == 1)
+ − emr_params.amr_facch_present = FALSE;
+ − emr_params.amr_facch_fire1 = FALSE;
+ − #endif
+ − #endif
+ − #endif
+ −
+ − // Increment number of burst not sent due to DTX.
+ − if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_u & 0xffff) == TCH_DTX_UL)
+ − {
+ − l1a_l1s_com.Smeas_dedic.dtx_used++;
+ − l1s.dtx_ul_on = TRUE;
+ − }
+ − else
+ − {
+ − // Some bursts are always sent in DTX mode. d_task_u does not give DTX_UL
+ − // so we must keep previous value of dtx_on
+ − if (! ((fn_mod_104 > 52) && (fn_mod_104 <= 60)) )
+ − l1s.dtx_ul_on = FALSE;
+ − }
+ −
+ − #if FF_L1_IT_DSP_DTX
+ − // Currently used for TCH-AFS only
+ − if (l1s.actual_time.fn_mod13_mod4 == 0) // FN%13 = 4, 8 and 12 (no TCH/F Read on FN%13=0)
+ − {
+ − // Latch TX activity status if DTX allowed
+ − if ((l1a_l1s_com.dedic_set.aset->dtx_allowed == FALSE) || // No DTX allowed
+ − (l1s_dsp_com.dsp_ndb_ptr->d_fast_dtx_enc_data) || // DTX allowed but not used
+ − (l1a_apihisr_com.dtx.fast_dtx_ready == FALSE)) // Fast DTX status is invalid
+ − l1a_apihisr_com.dtx.tx_active = TRUE;
+ − else
+ − l1a_apihisr_com.dtx.tx_active = FALSE;
+ − }
+ − #endif
+ −
+ − #if (AMR == 1)
+ − if (channel_mode != TCH_AFS_MODE)
+ − {
+ − // This AGC and TOA update isn't applied to the adaptative full rate mode
+ − #endif
+ −
+ − if((fn_mod_104 > 52) && (fn_mod_104 <= 60))
+ − // Current results are from the TDMA frame subset always received (GSM05.08, $8.3).
+ − // -> pwr meas. must be used for SUB set result.
+ − // -> TOA filtering can be fed with SNR/TOA.
+ − // This DTX is only applied to the mode EFR, FR and data.
+ − {
+ − // Update AGC: Call DPAGC algorithm
+ − IL_for_rxlev = l1ctl_dpagc(1,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+ −
+ − // Dedicated mode serving cell measurement reading, indicate "SUB".
+ − #if REL99
+ − #if FF_EMR
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 1, &emr_params);
+ − #endif
+ − #else
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 1);
+ − #endif
+ −
+ − //Feed TOA histogram.
+ − #if (TOA_ALGO != 0)
+ − #if (TOA_ALGO == 2)
+ − if(l1s.toa_var.toa_snr_mask == 0)
+ − #else
+ − if(l1s.toa_snr_mask == 0)
+ − #endif
+ − {
+ − #if 1 /* FreeCalypso TCS211 reconstruction */
+ − if (IL_for_rxlev < IL_FOR_RXLEV_SNR)
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa, &l1s.toa_update, &l1s.toa_period_count);
+ − else
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa, &l1s.toa_update, &l1s.toa_period_count);
+ − #else
+ − UWORD32 snr_temp;
+ − snr_temp = (IL_for_rxlev < IL_FOR_RXLEV_SNR)? snr: 0;
+ − #if (TOA_ALGO == 2)
+ − l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa);
+ − #else
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa, &l1s.toa_update, &l1s.toa_period_count
+ − #if (FF_L1_FAST_DECODING == 1)
+ − ,0
+ − #endif
+ − );
+ − #endif
+ − #endif
+ − }
+ − #endif
+ − }
+ − else
+ − {
+ − // Update AGC: Call DPAGC algorithm
+ − IL_for_rxlev = l1ctl_dpagc(0,beacon,(UWORD8)pm,radio_freq,IL_info_ptr);
+ −
+ − // Dedicated mode serving cell measurement reading, full set only.
+ − #if REL99
+ − #if FF_EMR
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+ − #endif
+ − #else
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+ − #endif
+ − }
+ − #if (AMR == 1)
+ − } // if (channel_mode != TCH_AFS_MODE)
+ − #endif
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − RTTL1_FILL_DL_BURST(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev)
+ − #endif
+ − #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4)) && HAVE_L1_TRACE_BURST_PARAM
+ − l1_trace_burst_param(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev);
+ − #endif
+ − #if (BURST_PARAM_LOG_ENABLE == 1)
+ − l1_log_burst_param(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev);
+ − #endif
+ −
+ − // Read downlink DATA block from MCU/DSP interface.
+ − // *************************************************
+ −
+ − // Compute FN in reporting period % 13 % 4.
+ − fn_report_mod13_mod4 = (l1s.actual_time.fn_mod13) % 4;
+ −
+ − if(fn_report_mod13_mod4 == 0)
+ − // It is time to get FACCH/F or TCH/F2.4 or TCH/(E)FS data block.
+ − {
+ − UWORD8 temp;
+ − #if TRACE_TYPE==3
+ − if (l1_stats.type == PLAY_UL &&
+ − (channel_mode == TCH_FS_MODE || channel_mode == TCH_24F_MODE
+ − || channel_mode == TCH_EFR_MODE))
+ − play_trace();
+ − #endif
+ −
+ − // FACCH: Check A_FD information block.
+ − //-------------------------------------
+ −
+ − b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_BLUD)) >> B_BLUD;
+ − #if ((REL99) && (AMR == 1))
+ − #if FF_EMR
+ − emr_params.amr_facch_fire1 = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_FIRE1)) >> B_FIRE1;
+ − #endif
+ − #endif
+ −
+ − if(b_blud == TRUE)
+ − {
+ − // Read FACCH DL data block from DSP, pass it to L2.
+ − #if ( FF_REPEATED_DL_FACCH == 1 )
+ − #if (TRACE_TYPE == 1 || TRACE_TYPE == 4)
+ − trace_info.facch_dl_count_all++;
+ − #endif
+ − /* if the current block is a repetition reports NULL to L2 otherwise reports the current block */
+ − l1s_read_dcch_dl((API*)l1s_repeated_facch_check(l1s_dsp_com.dsp_ndb_ptr->a_fd), task);
+ − #else
+ − /* UWORD8 error_flag =*/ l1s_read_dcch_dl(l1s_dsp_com.dsp_ndb_ptr->a_fd, task);
+ − #endif /* ( FF_REPEATED_DL_FACCH == 1 ) */
+ −
+ − #if (AMR == 1)
+ − // Non AMR FACCH handling
+ − if (channel_mode != TCH_AFS_MODE)
+ − {
+ − #endif
+ −
+ − // RXQUAL_SUB : In case of data taffic channels, accumulate number of
+ − // estimated errors, this value is contained in a_fd[2] field, only
+ − // for SID TDMA frames received as FACCH frames. (GSM 5.08 $8.4)
+ − if (fn_mod_104==60)
+ − {
+ − l1a_l1s_com.Smeas_dedic.qual_acc_sub += l1s_dsp_com.dsp_ndb_ptr->a_fd[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += TCH_F_D_BLEN;
+ − }
+ −
+ − #if (AMR == 1)
+ − }
+ − else
+ − {
+ − // AGC, RXLEV_FULL
+ −
+ − // Indicate to AMR specific processing that burst was a FACCH
+ − facch_present = TRUE;
+ − #if ((REL99) && (AMR == 1))
+ − #if FF_EMR
+ − emr_params.amr_facch_present = facch_present;
+ − #endif
+ − #endif
+ −
+ − // Update AGC: Call DPAGC algorithm
+ − IL_for_rxlev = l1ctl_dpagc_amr(0,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+ −
+ − // Dedicated mode serving cell measurement reading, indicate "FULL".
+ − #if REL99
+ − #if FF_EMR
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+ − #endif
+ − #else
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+ − #endif
+ − }
+ − #endif
+ −
+ − // RXQUAL_FULL : accumulate number of estimated errors, this value is
+ − // contained in a_fd[2] field, for each TCHT block.
+ − #if (AMR == 1)
+ − // in AMR, l1s.dtx_amr_dl_on is FALSE if DTX mode is off
+ − // in non AMR TCH, l1s.dtx_amr_dl_on is always FALSE
+ − // In AMR DTX, DSP patch sometimes reports FACCH blocks which ARE NOT FACCH blocks
+ − // therefore they shouldn't be taken into account in the RXQUALL_FULL computation
+ − if(l1s.dtx_amr_dl_on==FALSE)
+ − #endif
+ − {
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_fd[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_F_D_BLEN;
+ − }
+ −
+ −
+ −
+ −
+ −
+ −
+ −
+ −
+ −
+ − // Reset A_FD header.
+ − // B_FIRE1 =1, B_FIRE0 =0 , BLUD =0
+ − l1s_dsp_com.dsp_ndb_ptr->a_fd[0] = (1<<B_FIRE1);
+ − l1s_dsp_com.dsp_ndb_ptr->a_fd[2] = 0xffff;
+ −
+ − // Rem: when FACCH is received, we must reset A_DD_0 header also.
+ − // Reset A_DD_0 header in NDB.
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] = 0;
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+ −
+ − // Rem: when FACCH is received, we must reset A_DD_1 header also.
+ − // Reset A_DD_0 header in NDB.
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] = 0;
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] = 0xffff;
+ −
+ − #if TESTMODE
+ − if (l1_config.TestMode)
+ − {
+ − pm_fullres = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM] & 0xffff); // F26.6
+ −
+ − // Allocate result message.
+ − msg = os_alloc_sig(sizeof(T_TMODE_TCH_INFO));
+ − DEBUGMSG(status,NU_ALLOC_ERR)
+ − msg->SignalCode = TMODE_TCH_INFO;
+ −
+ − ((T_TMODE_TCH_INFO *)(msg->SigP))->pm_fullres = pm_fullres; // F26.6
+ − ((T_TMODE_TCH_INFO *)(msg->SigP))->snr = snr;
+ − ((T_TMODE_TCH_INFO *)(msg->SigP))->toa = toa;
+ − ((T_TMODE_TCH_INFO *)(msg->SigP))->angle = (WORD16) angle; // signed
+ − ((T_TMODE_TCH_INFO *)(msg->SigP))->qual_full = l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+ − ((T_TMODE_TCH_INFO *)(msg->SigP))->qual_nbr_meas_full = TCH_FS_BLEN;
+ −
+ − // send TMODE_TCH_INFO message...
+ − os_send_sig(msg, L1C1_QUEUE);
+ − DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+ − }
+ − #endif
+ − } // if (b_blud == TRUE)
+ −
+ − else // (if (b_blud == TRUE) FACCH
+ − {
+ − // No FACCH received.
+ −
+ − // Dummy: Read FACCH DL data block from DSP, pass it to L2.
+ − // Rem: this is an upper layer requirement to call this
+ − // function at every FACCH DL boundary.
+ − l1s_read_dcch_dl(NULL, task);
+ −
+ − #if (AMR == 1)
+ − if (channel_mode != TCH_AFS_MODE)
+ − {
+ − #endif
+ −
+ − // Check A_DD_0 information block for TCH/F2.4 or TCH/FS.
+ − // TCH/F2.4 or TCH/FS: Check A_DD_0 information block.
+ − //----------------------------------------------------
+ −
+ − b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+ − if(b_blud == TRUE)
+ − {
+ − // RXQUAL_SUB : In case of speech traffic channels, accumulate number of
+ − // estimated errors, this value is contained in a_dd_0[2] field, only
+ − // for SID TDMA frames. (GSM 5.08 $8.4)
+ − if (fn_mod_104==60)
+ − {
+ − l1a_l1s_com.Smeas_dedic.qual_acc_sub += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += TCH_FS_BLEN;
+ − }
+ −
+ − // RXQUAL_FULL : accumulate number of estimated errors, this value is
+ − // contained in a_dd_0[2] field, for each TCHT block.
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_FS_BLEN;
+ −
+ − #if TESTMODE
+ − if (l1_config.TestMode)
+ − {
+ − pm_fullres = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM] & 0xffff); // F26.6
+ −
+ − // Allocate result message.
+ − msg = os_alloc_sig(sizeof(T_TMODE_TCH_INFO));
+ − DEBUGMSG(status,NU_ALLOC_ERR)
+ − msg->SignalCode = TMODE_TCH_INFO;
+ −
+ − ((T_TMODE_TCH_INFO *)(msg->SigP))->pm_fullres = pm_fullres; // F26.6
+ − ((T_TMODE_TCH_INFO *)(msg->SigP))->snr = snr;
+ − ((T_TMODE_TCH_INFO *)(msg->SigP))->toa = toa;
+ − ((T_TMODE_TCH_INFO *)(msg->SigP))->angle = (WORD16) angle; // signed
+ − ((T_TMODE_TCH_INFO *)(msg->SigP))->qual_full = l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+ − ((T_TMODE_TCH_INFO *)(msg->SigP))->qual_nbr_meas_full = TCH_FS_BLEN;
+ −
+ − // send TMODE_TCH_INFO message...
+ − os_send_sig(msg, L1C1_QUEUE);
+ − DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+ − }
+ − #endif
+ −
+ − if(channel_mode == TCH_24F_MODE)
+ − {
+ − #if IDS
+ − // Integrated Data Services implementation
+ − {
+ − dll_data_dl(l1s_dsp_com.dsp_ndb_ptr->a_data_buf_dl,
+ − &l1s_dsp_com.dsp_ndb_ptr->d_ra_act,
+ − &l1s_dsp_com.dsp_ndb_ptr->d_ra_statd);
+ − }
+ − #else
+ − {
+ − // DATA traffic.
+ − // Pass data block to DATA ADAPTOR.
+ − // REM: Data packet is always given to the DATA ADAPTOR.
+ − // There is no RX quality check !!
+ − {
+ − rx_tch_data(&l1s_dsp_com.dsp_ndb_ptr->a_dd_0[3], channel_mode, 0);
+ − }
+ − }
+ − #endif
+ − }
+ −
+ − // Reset A_DD_0 header in NDB.
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] = 0;
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+ − } // if(b_blud == TRUE)
+ − #if (AMR == 1)
+ − } // if (channel_mode != TCH_AFS_MODE)
+ − #endif
+ − } // if (b_blud == TRUE) FACCH (else)
+ − #if (FF_REPEATED_DL_FACCH == 1)
+ − #if 1
+ − temp=l1s.repeated_facch.counter_candidate;
+ − l1s.repeated_facch.counter_candidate=l1s.repeated_facch.counter;
+ − l1s.repeated_facch.counter=temp;
+ − #else
+ − if (l1s.repeated_facch.counter_candidate == 1)
+ − l1s.repeated_facch.counter_candidate = 0 ;
+ − else if (l1s.repeated_facch.counter_candidate == 0 )
+ − l1s.repeated_facch.counter_candidate = 0 ;
+ −
+ − l1s.repeated_facch.counter++ ;
+ − if (l1s.repeated_facch.counter == 4)
+ − {
+ − l1s.repeated_facch.counter = 0;
+ − l1s.repeated_facch.pipeline[0].buffer_empty=l1s.repeated_facch.pipeline[1].buffer_empty=TRUE;
+ − }
+ − #endif
+ − #endif/*(FF_REPEATED_DL_FACCH == 1)*/
+ − /* FACCH Full rate */
+ − } // if(fn_report_mod13_mod4 == 0)
+ −
+ − else // if(fn_report_mod13_mod4 == 0)
+ − #if (AMR == 1)
+ − if ((fn_report_mod13_mod4 == 2) && (channel_mode != TCH_AFS_MODE))
+ − #else
+ − if(fn_report_mod13_mod4 == 2)
+ − #endif
+ − // It is time to get TCH/F4.8 or TCH/F9.6 data block.
+ − {
+ − #if TRACE_TYPE==3
+ − if (l1_stats.type == PLAY_UL &&
+ − (channel_mode == TCH_48F_MODE || channel_mode == TCH_96_MODE || channel_mode == TCH_144_MODE))
+ − play_trace();
+ − #endif
+ −
+ − // Check A_DD_0 information block only if no FACCH.
+ − b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+ − if(b_blud == TRUE)
+ − {
+ − // RXQUAL_FULL : accumulate number of estimated errors, this value is
+ − // contained in a_dd_0[2] field, for each TCHT block.
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_F_D_BLEN;
+ −
+ − if((channel_mode == TCH_48F_MODE) || (channel_mode == TCH_96_MODE) || (channel_mode == TCH_144_MODE))
+ − {
+ − #if IDS
+ − // Integrated Data Services implementation
+ − {
+ − dll_data_dl(l1s_dsp_com.dsp_ndb_ptr->a_data_buf_dl,
+ − &l1s_dsp_com.dsp_ndb_ptr->d_ra_act,
+ − &l1s_dsp_com.dsp_ndb_ptr->d_ra_statd);
+ − }
+ − #else
+ − {
+ − // DATA traffic.
+ − // Pass data block to DATA ADAPTOR.
+ − // REM: Data packet is always given to the DATA ADAPTOR.
+ − // There is no RX quality check !!
+ − {
+ − UWORD8 sequence_number;
+ − UWORD8 fn_report_mod26 = l1s.actual_time.fn_in_report % 26;
+ −
+ − // Catch sequence number. This is used in TCH/F4.8 to distinguish
+ − // data blocks (see GSM 5.02) received on B0,B2,B4 (sequence number 0)
+ − // and data blocks received on B1,B2,B3 (sequence number 1).
+ − if((fn_report_mod26 == 23) || (fn_report_mod26 == 6) || (fn_report_mod26 == 15))
+ − sequence_number = 0;
+ − else
+ − sequence_number = 1;
+ − rx_tch_data(&l1s_dsp_com.dsp_ndb_ptr->a_dd_0[3], channel_mode, sequence_number);
+ − }
+ − }
+ − #endif
+ − }
+ − // Reset A_DD_0 header in NDB.
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] = 0;
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+ − } // if(b_blud == TRUE)
+ − } // if(fn_report_mod13_mod4 == 2)
+ −
+ − #if (AMR == 1)
+ − if ((channel_mode == TCH_AFS_MODE) && (facch_present == FALSE))
+ − {
+ − // Load the bit to check if the block is valid
+ − b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+ −
+ − // Load the bit to check if the block is a RATSCCH in case of rx_type = NO_DATA
+ − b_ratscch_blud = (l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0] & (1<<B_BLUD)) >> B_BLUD;
+ −
+ − // All detected AMR frames except NO_DATA (b_blud = 0) and FACCH are handled here, i.e. speech/SID/RATSCCH
+ − if(b_ratscch_blud==TRUE)
+ − {
+ − // RXQUAL_FULL : accumulate number of estimated errors, this value is
+ − // contained in a_ratscch_dl[2] field, for each TCHT block.
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[2] & 0xffff;
+ −
+ − // Reset the A_RATSCCH_DL header in NDB.
+ − l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0] = 0;
+ − l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[2] = 0xffff;
+ −
+ − // RXQUAL_FULL : the number of bits examined for errors on serving cell depends on
+ − // the block received.
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += RATSCCH_BLEN;
+ −
+ − IL_for_rxlev = l1ctl_dpagc_amr(0,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+ − #if REL99
+ − #if FF_EMR
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+ − #endif
+ − #else
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+ − #endif
+ − }
+ − else if(b_blud==TRUE)
+ − {
+ − // Load the type of the block received
+ − rx_type = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+ −
+ − #if (DEBUG_DEDIC_TCH_BLOCK_STAT == 1)
+ − Trace_dedic_tch_block_stat(rx_type, l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2], 0);
+ − #endif
+ −
+ − // RXQUAL_SUB : In case of adaptative traffic channel, accumulate number of estimated errors
+ − // is contained in the a_dd_0[2] value but the accumulation is made with SID_UPDATE frame only.
+ − // Note: SID_UPDATE frame corresponds to rx_type SID_UPDATE (b_ratscch_blud = FALSE) or SID_BAD (See Memo)
+ − if((rx_type==SID_UPDATE) || (rx_type==SID_BAD))
+ −
+ − {
+ − l1a_l1s_com.Smeas_dedic.qual_acc_sub += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += SID_UPDATE_BLEN;
+ − }
+ −
+ − // RXQUAL_FULL : accumulate number of estimated errors, this value is
+ − // contained in a_dd_0[2] field, for each TCHT block.
+ −
+ −
+ −
+ −
+ − // Frames, which have no class1 bit (so no quality meas is possible), have d_nerr = 0
+ − // so we can add them
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+ −
+ − // Reset A_DD_0 header in NDB.
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] = 0;
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+ −
+ −
+ −
+ −
+ −
+ − // RXQUAL_FULL : the number of bits examined for errors on serving cell depends on
+ − // the block received.
+ − if((rx_type==SPEECH_GOOD) || (rx_type==SPEECH_DEGRADED) || (rx_type==SPEECH_BAD))
+ − {
+ − // It's a speech block
+ − // Note: in AFS, the d_nerr value doesn't depend on the vocoder currently use
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AFS_BLEN;
+ − }
+ − else if((rx_type==SID_UPDATE) || (rx_type==SID_BAD))
+ −
+ −
+ − {
+ − // the block is a SID UPDATE frame
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += SID_UPDATE_BLEN;
+ − }
+ −
+ −
+ −
+ −
+ −
+ −
+ −
+ − // AGC, TOA, RXLEV for AMR. SUB queues only for SID_UPDATE frames
+ − if((rx_type==SID_UPDATE) || (rx_type==SID_BAD))
+ −
+ − {
+ − IL_for_rxlev = l1ctl_dpagc_amr(1,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+ − #if REL99
+ − #if FF_EMR
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 1, &emr_params);
+ − #endif
+ − #else
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 1);
+ − #endif
+ −
+ − #if (TOA_ALGO != 0)
+ − #if (TOA_ALGO == 2)
+ − if(l1s.toa_var.toa_snr_mask == 0)
+ − #else
+ − if(l1s.toa_snr_mask == 0)
+ − #endif
+ − {
+ − #if 1 /* FreeCalypso TCS211 reconstruction */
+ − if (IL_for_rxlev < IL_FOR_RXLEV_SNR)
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa, &l1s.toa_update, &l1s.toa_period_count);
+ − else
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa, &l1s.toa_update, &l1s.toa_period_count);
+ − #else
+ − UWORD32 snr_temp;
+ − snr_temp = (IL_for_rxlev < IL_FOR_RXLEV_SNR)? snr: 0;
+ − #if (TOA_ALGO == 2)
+ − l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa);
+ − #else
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa, &l1s.toa_update, &l1s.toa_period_count
+ − #if (FF_L1_FAST_DECODING == 1)
+ − ,0
+ − #endif
+ − );
+ − #endif
+ − #endif
+ − }
+ − #endif
+ − }
+ − else
+ − {
+ − IL_for_rxlev = l1ctl_dpagc_amr(0,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+ − #if REL99
+ − #if FF_EMR
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+ − #endif
+ − #else
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+ − #endif
+ − }
+ − } // if(b_blud==TRUE)
+ − // NO_DATA block detected or simple burst
+ − else
+ − {
+ − if (fn_report_mod13_mod4 == 0)
+ − {
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AFS_BLEN;
+ −
+ − #if (DEBUG_DEDIC_TCH_BLOCK_STAT == 1)
+ − Trace_dedic_tch_block_stat(AMR_NO_DATA, l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2], 0);
+ − #endif
+ −
+ − // Reset A_DD_0 header in NDB.
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] = 0;
+ − l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+ − }
+ −
+ − // Update AGC: Call DPAGC AMR algorithm in order to fill the G_all buffer
+ − IL_for_rxlev = l1ctl_dpagc_amr(0,beacon,(UWORD8)pm,radio_freq,IL_info_ptr);
+ −
+ − // Dedicated mode serving cell measurement reading, full set only.
+ − #if REL99
+ − #if FF_EMR
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+ − #endif
+ − #else
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+ − #endif
+ − }
+ − } // if ((channel_mode == TCH_AFS_MODE) && (facch_present == FALSE))
+ − #endif
+ −
+ − // task is completed, make it INACTIVE.
+ − l1s.task_status[task].current_status = INACTIVE;
+ − }
+ − break;
+ −
+ − case TCHA:
+ − /*---------------------------------------------------*/
+ − /* Dedicated mode: SACCH receive task. */
+ − /*---------------------------------------------------*/
+ − {
+ − UWORD8 IL_for_rxlev;
+ − UWORD32 b_blud;
+ −
+ − // Read control results and feed control algorithms.
+ − // **************************************************
+ −
+ − // Read control information.
+ − toa = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_TOA] & 0xffff;
+ − pm = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM] & 0xffff) >> 5;
+ − angle = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_ANGLE] & 0xffff;
+ − snr = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_SNR] & 0xffff;
+ −
+ − #if TESTMODE
+ − if (l1_config.TestMode && l1_config.tmode.rf_params.down_up == TMODE_UPLINK)
+ − {
+ − // For UL-only tasks, TCHA is scheduled in every frame. TCH_INFO message is only
+ − // used to count loops; no stats are collected.
+ −
+ − xSignalHeaderRec *msg;
+ − // Allocate result message.
+ − msg = os_alloc_sig(sizeof(T_TMODE_TCH_INFO));
+ − DEBUGMSG(status,NU_ALLOC_ERR)
+ − msg->SignalCode = TMODE_TCH_INFO;
+ − // send TMODE_TCH_INFO message...
+ − os_send_sig(msg, L1C1_QUEUE);
+ − DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+ − }
+ − // WARNING!
+ − // Don't trace PM=0 during UL-only in TestMode. The DSP is not working
+ − // in that case so it is normal. However, if tracing happens the CPU overloads
+ − if (l1_config.TestMode && l1_config.tmode.rf_params.down_up & TMODE_DOWNLINK)
+ − #endif
+ − {
+ − l1_check_pm_error(pm, task);
+ − }
+ −
+ − #if TRACE_TYPE==3
+ − stats_samples_tch_sacch(toa,pm,angle,snr);
+ − #endif
+ −
+ − #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+ − uart_trace(task);
+ − #endif
+ −
+ − // Update AGC: Call DPAGC algorithm
+ − IL_for_rxlev = l1ctl_dpagc(1,beacon,(UWORD8)pm,radio_freq,IL_info_ptr); // dtx_on = 1
+ −
+ − // Dedicated mode serving cell measurement reading, indicate "SUB".
+ − #if REL99
+ − #if FF_EMR
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 1, &emr_params);
+ − #endif
+ − #else
+ − l1s_read_dedic_scell_meas(IL_for_rxlev, 1);
+ − #endif
+ −
+ − // Update AFC: Call AFC control function (KALMAN filter).
+ − #if AFC_ALGO
+ − #if TESTMODE
+ − if (l1_config.afc_enable)
+ − #endif
+ − {
+ − #if (VCXO_ALGO == 0)
+ − l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq);
+ − #else
+ − l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq,l1a_l1s_com.mode);
+ − #endif
+ − }
+ − #endif
+ −
+ − //Feed TOA histogram.
+ − #if (TOA_ALGO != 0)
+ − #if (TOA_ALGO == 2)
+ − if(l1s.toa_var.toa_snr_mask == 0)
+ − #else
+ − if(l1s.toa_snr_mask == 0)
+ − #endif
+ − {
+ − #if 1 /* FreeCalypso TCS211 reconstruction */
+ − if (IL_for_rxlev < IL_FOR_RXLEV_SNR)
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa, &l1s.toa_update, &l1s.toa_period_count);
+ − else
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa, &l1s.toa_update, &l1s.toa_period_count);
+ − #else
+ − UWORD32 snr_temp;
+ − snr_temp = (IL_for_rxlev < IL_FOR_RXLEV_SNR)? snr: 0;
+ − #if (TOA_ALGO == 2)
+ − l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa);
+ − #else
+ − l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa, &l1s.toa_update, &l1s.toa_period_count
+ − #if (FF_L1_FAST_DECODING == 1)
+ − ,0
+ − #endif
+ − );
+ − #endif
+ − #endif
+ − }
+ − #endif
+ −
+ − #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+ − RTTL1_FILL_DL_BURST(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev)
+ − #endif
+ − #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4)) && HAVE_L1_TRACE_BURST_PARAM
+ − l1_trace_burst_param(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev);
+ − #endif
+ − #if (BURST_PARAM_LOG_ENABLE == 1)
+ − l1_log_burst_param(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev);
+ − #endif
+ −
+ − // Read downlink DATA block from MCU/DSP interface.
+ − // *************************************************
+ −
+ − if(l1s.actual_time.fn_in_report == 91)
+ − // It's time to read a SACCH DL result from DSP.
+ − {
+ − // Check A_CD information block.
+ − b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_cd[0] & (1<<B_BLUD)) >> B_BLUD;
+ − if(b_blud == TRUE)
+ − {
+ − #if W_A_DSP1
+ − // Temporary correction to fix a known DSP problem. SACCH deinterleaver not
+ − // initialized on HO.
+ − //
+ − if (old_sacch_DSP_bug == TRUE)
+ − {
+ − // Invalidate the current sacch block - indicate it cannot be decoded
+ − l1s_dsp_com.dsp_ndb_ptr->a_cd[0] = (1<<B_FIRE1); // B_FIRE1=1,B_FIRE0=0,BLUD=0.
+ − old_sacch_DSP_bug = FALSE;
+ − }
+ − #endif
+ −
+ − // Read data block and send msg to L1A.
+ − l1s_read_sacch_dl(l1s_dsp_com.dsp_ndb_ptr->a_cd, task);
+ −
+ − // RXQUAL_FULL/RXQUAL_SUB : Accumulate number of estimated errors, this value
+ − // is contained in a_cd[2] field, for every SACCH block.
+ − l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_cd[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += A_D_BLEN;
+ − l1a_l1s_com.Smeas_dedic.qual_acc_sub += l1s_dsp_com.dsp_ndb_ptr->a_cd[2] & 0xffff;
+ − l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += A_D_BLEN;
+ −
+ − // TEMPORARY : reset buffers and flags in NDB ...
+ − // reset nerr....
+ − // reset A_CD contents.......
+ − l1s_dsp_com.dsp_ndb_ptr->a_cd[0] = (1<<B_FIRE1); // B_FIRE1=1,B_FIRE0=0,BLUD=0.
+ − l1s_dsp_com.dsp_ndb_ptr->a_cd[2] = 0xffff;
+ − }
+ − }
+ − #if W_A_DSP1
+ − else if (l1s.actual_time.fn_in_report == 13) // TF 5/8/98 - DSP fix
+ − {
+ − // As this is the first SACCH burst the known DSP bug cannot occur on a new channel.
+ − old_sacch_DSP_bug = FALSE;
+ − }
+ − #endif
+ −
+ − // task is completed, make it INACTIVE.
+ − l1s.task_status[task].current_status = INACTIVE;
+ − }
+ − break;
+ − } // End switch...
+ −
+ − #if (L1_DEBUG_IQ_DUMP == 1)
+ − l1ddsp_read_iq_dump(task);
+ − #endif
+ −
+ − // Flag the use of the MCU/DSP dual page read interface.
+ − // ******************************************************
+ −
+ − // Set flag used to change the read page at the end of "l1_synch".
+ − l1s_dsp_com.dsp_r_page_used = TRUE;
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_read_tx_result() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − void l1s_read_tx_result(UWORD8 task, UWORD8 burst_id)
+ − {
+ − /*--------------------------------------------------------*/
+ − /* READ TRANSMIT TASK RESULTS... */
+ − /*--------------------------------------------------------*/
+ −
+ − #if (TRACE_TYPE!=0)
+ − if(task==RAACC)
+ − {
+ − if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_ra & 0xffff) != (UWORD32)DSP_TASK_CODE[task])
+ − trace_fct(CST_UL_TASKS_DO_NOT_CORRESPOND, -1);
+ − }
+ − else
+ − {
+ − if(((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_u & 0xffff) != (UWORD32)DSP_TASK_CODE[task]) &&
+ − ((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_u & 0xffff) != TCH_DTX_UL))
+ − trace_fct(CST_UL_TASKS_DO_NOT_CORRESPOND, -1);
+ − }
+ − #endif
+ −
+ − l1_check_com_mismatch(task);
+ −
+ − switch(task)
+ − {
+ − case RAACC:
+ − /*---------------------------------------------------*/
+ − /* Serving Cell: Random Access TX task. */
+ − /*---------------------------------------------------*/
+ − // Rem: confirmation message is sent at "CTRL" to be able to give FN%42432.
+ − {
+ − // Send confirmation msg to L1A.
+ − // ******************************
+ −
+ − // For ACCESS phase, a confirmation msg is sent to L1A.
+ − xSignalHeaderRec *msg;
+ −
+ − // send L1C_RA_DONE to L1A...
+ − msg = os_alloc_sig(sizeof(T_MPHC_RA_CON));
+ − DEBUGMSG(status,NU_ALLOC_ERR)
+ −
+ − if (l1s.actual_time.fn == 0)
+ − ((T_MPHC_RA_CON *)(msg->SigP))->fn = MAX_FN - 1;
+ − else
+ − ((T_MPHC_RA_CON *)(msg->SigP))->fn = l1s.actual_time.fn - 1;
+ −
+ − ((T_MPHC_RA_CON *)(msg->SigP))->channel_request = l1a_l1s_com.ra_info.channel_request;
+ − msg->SignalCode = L1C_RA_DONE;
+ −
+ − os_send_sig(msg, L1C1_QUEUE);
+ − DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+ −
+ − // Desactivate the RAACC task.
+ − l1s.task_status[task].current_status = INACTIVE;
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_READ_RA, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ − }
+ − break;
+ −
+ − case DUL:
+ − /*---------------------------------------------------*/
+ − /* Serving Cell: SDCCH up link. */
+ − /*---------------------------------------------------*/
+ − {
+ − // Desactivate UL task.
+ − if(burst_id == BURST_4)
+ − {
+ − l1s.task_status[task].current_status = INACTIVE;
+ −
+ − #if (TRACE_TYPE == 5) // in simulation only the 4th burst is traced
+ − trace_fct(CST_L1S_READ_TX_NB__DUL, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ − }
+ −
+ − #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+ − trace_fct(CST_L1S_READ_TX_NB__DUL, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ − }
+ − break;
+ −
+ − case AUL:
+ − /*---------------------------------------------------*/
+ − /* Serving Cell: SACCH up link. */
+ − /*---------------------------------------------------*/
+ − {
+ − // Desactivate UL task.
+ − if(burst_id == BURST_4)
+ − {
+ − l1s.task_status[task].current_status = INACTIVE;
+ −
+ − #if (TRACE_TYPE == 5) // in simulation only the 4th burst is traced
+ − trace_fct(CST_L1S_READ_TX_NB__AUL, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ − }
+ −
+ − #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+ − trace_fct(CST_L1S_READ_TX_NB__AUL, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − }
+ − break;
+ −
+ − case TCHA:
+ − case TCHTF:
+ − /*---------------------------------------------------*/
+ − /* Serving Cell: TCH link. */
+ − /*---------------------------------------------------*/
+ − {
+ − #if (TRACE_TYPE==5)
+ − if(burst_id == BURST_4) // in simulation only the 4th burst is traced
+ − trace_fct(CST_L1S_READ_TX_NB__TCHF, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+ − trace_fct(CST_L1S_READ_TX_NB__TCHF, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ − }
+ − break;
+ −
+ − case TCHTH:
+ − /*---------------------------------------------------*/
+ − /* Serving Cell: TCH link. */
+ − /*---------------------------------------------------*/
+ − {
+ − #if (TRACE_TYPE==5)
+ − if(burst_id == BURST_2) // in simulation only lates burst is traced
+ − trace_fct(CST_L1S_READ_TX_NB__TCHH, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+ − trace_fct(CST_L1S_READ_TX_NB__TCHH, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ − }
+ − break;
+ − }
+ −
+ − // Set flag used to change the read page at the end of "l1_synch".
+ − l1s_dsp_com.dsp_r_page_used = TRUE;
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_read_dedic_scell_meas() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ −
+ − #if REL99
+ − #if FF_EMR
+ − void l1s_read_dedic_scell_meas(UWORD8 input_level, UWORD8 sub_flag, T_EMR_PARAMS *emr_params)
+ − {
+ − UWORD8 task;
+ − UWORD8 burst_id;
+ − UWORD8 b_blud;
+ − UWORD8 counter;
+ − UWORD8 bfi; // band frame indicator
+ − UWORD8 channel_mode; // current channel type
+ − //OMAPS00090550 UWORD8 fn_report_mod_26;
+ − UWORD8 subchannel; // half rate sub channel
+ − UWORD8 sid_present; // indication for sid block
+ − UWORD16 rx_type;
+ − UWORD32 normalised_fn_mod13_mod4;
+ −
+ − UWORD16 mean_bep_lsb = 0; //l1s_dsp_com.dsp_ndb_ptr->d_mean_bep_block_lsb;
+ − UWORD16 mean_bep_msb = 0; //l1s_dsp_com.dsp_ndb_ptr->d_mean_bep_block_msb;
+ − UWORD32 mean_bep = 0; //((mean_bep_msb<<WORD_SHIFT)|(mean_bep_lsb)) >> MEAN_BEP_FORMAT;
+ − UWORD16 cv_bep = 0; //(l1s_dsp_com.dsp_ndb_ptr->d_cv_bep_block) >> CV_BEP_FORMAT;
+ −
+ − static WORD16 last_corr_decoded_burst[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ − static UWORD16 cv_bep_tch4_8f_144[2] = {0, 0};
+ − static UWORD32 mean_bep_tch4_8f_144[2] = {0, 0};
+ −
+ − WORD16 rxlev = l1s_encode_rxlev(input_level);
+ −
+ − if (l1s_dsp_com.dsp_r_page == 1)
+ − {
+ − cv_bep = l1s_dsp_com.dsp_ndb_ptr->a_mean_cv_bep_page_0[D_CV_BEP];
+ − mean_bep_msb = l1s_dsp_com.dsp_ndb_ptr->a_mean_cv_bep_page_0[D_MEAN_BEP_MSW];
+ − mean_bep_lsb = l1s_dsp_com.dsp_ndb_ptr->a_mean_cv_bep_page_0[D_MEAN_BEP_LSW];
+ − }
+ − else
+ − {
+ − cv_bep = l1s_dsp_com.dsp_ndb_ptr->a_mean_cv_bep_page_1[D_CV_BEP];
+ − mean_bep_msb = l1s_dsp_com.dsp_ndb_ptr->a_mean_cv_bep_page_1[D_MEAN_BEP_MSW];
+ − mean_bep_lsb = l1s_dsp_com.dsp_ndb_ptr->a_mean_cv_bep_page_1[D_MEAN_BEP_LSW];
+ − }
+ −
+ − mean_bep = ((mean_bep_msb<<WORD_SHIFT)|(mean_bep_lsb)) >> MEAN_BEP_FORMAT;
+ − cv_bep = cv_bep >> CV_BEP_FORMAT;
+ −
+ − // EMR : Copy of Legacy code begins
+ − // Measurement must be rejected if channel is hopping, hopped on
+ − // the beacon frequency and PWRC is TRUE (see GSM05.08, $8.1.3).
+ − if(!((l1a_l1s_com.dedic_set.pwrc == TRUE) &&
+ − (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->chan_sel.h == TRUE) &&
+ − (l1a_l1s_com.dedic_set.radio_freq_dd == l1a_l1s_com.Scell_info.radio_freq)))
+ − {
+ − // Add to FULL set meas.
+ − l1a_l1s_com.Scell_info.meas.nbr_meas++;
+ − l1a_l1s_com.Scell_info.meas.acc += rxlev;
+ −
+ − if(sub_flag == TRUE)
+ − {
+ − // Add to SUB set meas.
+ − l1a_l1s_com.Smeas_dedic.nbr_meas_sub++;
+ − l1a_l1s_com.Smeas_dedic.acc_sub += rxlev;
+ − } // if(sub_flag == TRUE)
+ − // EMR : Copy of Legacy code ends
+ − } // if(!((l1a_l1s_com.dedic_set.pwrc == TRUE) && ....
+ −
+ − // new rxlev is received. remove the oldest rxlev.
+ − for(counter=0;counter<=6;counter++)
+ − last_corr_decoded_burst[counter] = last_corr_decoded_burst[counter+1];
+ −
+ − // store new rxlev.
+ − last_corr_decoded_burst[7] = rxlev;
+ −
+ − task = emr_params->task;
+ − burst_id = emr_params->burst_id;
+ − channel_mode = emr_params->channel_mode;
+ − normalised_fn_mod13_mod4 = emr_params->normalised_fn_mod13_mod4;
+ −
+ − // TCH FS and TCH EFR
+ − if((task == TCHTF) &&
+ − (l1s.actual_time.fn_mod13_mod4 == 0) &&
+ − ((channel_mode == TCH_FS_MODE) ||
+ − (channel_mode == TCH_EFR_MODE) ||
+ − (channel_mode == SIG_ONLY_MODE)))
+ − {
+ − if(emr_params->facch_present == TRUE)
+ − {
+ − // FACCH
+ − if(emr_params->facch_fire1 == FALSE)
+ − {
+ − // FACCH correctly decoded
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ −
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ −
+ − if(channel_mode == SIG_ONLY_MODE)
+ − // accumulation of correctly decoded blocks excluding SACCH and SID frames FACCH only for sig only mode
+ − l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+ −
+ − } // if(facch_fire1 == FALSE)
+ − } // if(facch_present == TRUE )
+ − else
+ − {
+ − // NOT FACCH,
+ − if (emr_params->a_dd_0_blud == TRUE)
+ − {
+ − if (emr_params->a_dd_0_bfi == FALSE)
+ − {
+ − // speech correctly decoded
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ −
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ −
+ − if (emr_params->sid_present_sub0 == FALSE)
+ − {
+ − // accumulation of correctly decoded blocks excluding SACCH FACCH and SID frames
+ − l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+ − } // if(sid_present == FALSE)
+ − } // if(bfi == FALSE)
+ − } // if(b_blud == TRUE)
+ − } // else part of if(facch_present == TRUE )
+ − } // TCH FS and TCH EFR
+ −
+ − // TCH 2.4F
+ − if((task == TCHTF) &&
+ − (l1s.actual_time.fn_mod13_mod4 == 0) &&
+ − (channel_mode == TCH_24F_MODE))
+ − {
+ − if(emr_params->facch_present == TRUE)
+ − {
+ − if(emr_params->facch_fire1 == FALSE)
+ − {
+ − // FACCH correctly decoded
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ −
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ − }
+ − } // if(facch_present == TRUE)
+ − else
+ − {
+ − // NOT FACCH check whether the data buffer is updated!!
+ − if(emr_params->a_dd_0_blud == TRUE)
+ − {
+ − // Check if transparent data or not
+ − if(emr_params->b_ce == TRUE)// Non Transparent
+ − {
+ − //check if correctly decoded or not
+ − if(emr_params->a_ntd == FALSE)//good frame detected
+ − {
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ −
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ − // accumulation of correctly decoded blocks excluding SACCH FACCH frames
+ − l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+ − } // if(a_ntd == FALSE)
+ − } // if(b_ce == TRUE)
+ − else
+ − {
+ − // 2.4F transperent data (always considered as correctly decoded)
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ −
+ − //accumulation of the block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ −
+ − // accumulation of decoded blocks excluding SACCH FACCH and SID frames
+ − l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+ − } // if(b_ce == TRUE)
+ − } // if(b_blud == TRUE)
+ − } // else part of if(facch_present == TRUE)
+ − } // TCH 2.4F
+ −
+ − // TCH 9.6F
+ − if((task == TCHTF) &&
+ − (l1s.actual_time.fn_mod13_mod4 == 0) &&
+ − (channel_mode == TCH_96_MODE))
+ − {
+ − if(emr_params->facch_present == TRUE)
+ − {
+ − if(emr_params->facch_fire1 == FALSE)
+ − {
+ − // FACCH correctly decoded
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ −
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ − } //if(fire1 == FALSE)
+ − } //if(facch_present == TRUE)
+ − } // if(fn_mod13_mod4 == 0)
+ −
+ − if((task == TCHTF) &&
+ − (l1s.actual_time.fn_mod13_mod4 == 2) &&
+ − (channel_mode == TCH_96_MODE))
+ − {
+ − if(emr_params->a_dd_0_blud == TRUE)
+ − {
+ − // Check if transparent data or not
+ − if(emr_params->b_ce == TRUE)// Non Transparent
+ − {
+ − //check if correctly decoded or not
+ − if(emr_params->a_ntd == FALSE)//good frame detected
+ − {
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ −
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ −
+ − // accumulation of correctly decoded blocks excluding SACCH FACCH frames
+ − l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+ − } // if(a_ntd == FALSE)
+ − } // if(b_ce == TRUE)
+ − else
+ − {
+ − // transparent data (always correctly decoded)
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ −
+ − //accumulation of decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ −
+ − // accumulation of decoded blocks excluding SACCH FACCH frames
+ − l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+ − } // transparent data
+ − } // if(b_blud == TRUE)
+ − } // TCH F9.6
+ −
+ − // TCH 4.8F/14.4F
+ − if((task == TCHTF) &&
+ − (l1s.actual_time.fn_mod13_mod4 == 0) &&
+ − ((channel_mode == TCH_48F_MODE) || (channel_mode == TCH_144_MODE)) )
+ − {
+ − if(emr_params->facch_present == TRUE)
+ − {
+ − if(emr_params->facch_fire1 == FALSE)
+ − {
+ − // FACCH correctly decoded
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;// 4 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ −
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ − } //if(fire1 == FALSE)
+ − } //if(facch_present == TRUE)
+ − } // if(fn_mod13_mod4 == 0)
+ −
+ − if((task == TCHTF) &&
+ − (l1s.actual_time.fn_mod13_mod4 == 2) &&
+ − ((channel_mode == TCH_48F_MODE) || (channel_mode == TCH_144_MODE)) )
+ − {
+ − // block end add new value of mean_bep and cv_bep value to mean_bep_tch4_8f_144 and
+ − // cv_bep_tch4_8f_144. remove the oldest value.
+ − mean_bep_tch4_8f_144[0] = mean_bep_tch4_8f_144[1];
+ − cv_bep_tch4_8f_144[0] = cv_bep_tch4_8f_144[1];
+ − mean_bep_tch4_8f_144[1] = mean_bep;
+ − cv_bep_tch4_8f_144[1] = cv_bep;
+ −
+ − if ( ((emr_params->a_dd_0_blud == TRUE) && (emr_params->b_m1) && (channel_mode == TCH_144_MODE)) ||
+ − ((emr_params->a_dd_0_blud == TRUE) && (emr_params->b_f48blk_dl) && (channel_mode == TCH_48F_MODE)) )
+ − {
+ − // Check if transparent data or not
+ − if(emr_params->b_ce == TRUE) // Non transparent
+ − {
+ − //check if correctly decoded or not. Accumulate last 8 slots
+ − if(emr_params->a_ntd == FALSE) //good frame detected
+ − {
+ − // two blocks are accumulated at a time, increment by 2.
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas+=8; // 8 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep_tch4_8f_144[0] + mean_bep_tch4_8f_144[1];
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep_tch4_8f_144[0] + cv_bep_tch4_8f_144[1];
+ −
+ − // two blocks are accumulated at a time, increment by 2.
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num += 2;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num+=2;
+ −
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[0] +
+ − last_corr_decoded_burst[1] +
+ − last_corr_decoded_burst[2] +
+ − last_corr_decoded_burst[3] +
+ − last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ −
+ − // accumulation of correctly decoded blocks excluding SACCH FACCH frames
+ − l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks +=2;
+ − } // if(a_ntd == FALSE)
+ − } // if(b_ce == TRUE)
+ − else
+ − {
+ − // transparent data
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=8; // 8 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep_tch4_8f_144[0] + mean_bep_tch4_8f_144[1];
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep_tch4_8f_144[0] + cv_bep_tch4_8f_144[1];
+ −
+ − // two blocks are accumulated at a time, increment by 2.
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num+=2;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num += 2;
+ −
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[0] +
+ − last_corr_decoded_burst[1] +
+ − last_corr_decoded_burst[2] +
+ − last_corr_decoded_burst[3] +
+ − last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ −
+ − // accumulation of correctly decoded blocks excluding SACCH FACCH frames
+ − l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks +=2;
+ − } // Transparent data
+ − } // if(b_blud == TRUE)
+ − } // TCH 4.8F/14.4
+ −
+ −
+ − // TCH HS
+ − if((task == TCHTH) &&
+ − ((channel_mode == TCH_HS_MODE)||(channel_mode == SIG_ONLY_MODE))&&
+ − (normalised_fn_mod13_mod4 == 3) )
+ − {
+ − UWORD8 norm_fn_mod26;
+ −
+ − subchannel = emr_params->subchannel;
+ − norm_fn_mod26 = ((l1s.actual_time.fn - subchannel + 26) % 26);
+ −
+ − if(subchannel == 0)
+ − {
+ − b_blud = emr_params->a_dd_0_blud;
+ − bfi = emr_params->a_dd_0_bfi; // 3rd bit tells the BAD frame.
+ − sid_present = emr_params->sid_present_sub0; // find out whether sid1 is 0/1, 1 mean
+ − }
+ − else
+ − {
+ − b_blud = emr_params->a_dd_1_blud;
+ − bfi = emr_params->a_dd_1_bfi; // 3rd bit tells the BAD frame.
+ − sid_present = emr_params->sid_present_sub1; // find out whether sid1 is 0/1, 1 mean
+ − }
+ −
+ − if(norm_fn_mod26 == 7 || norm_fn_mod26 == 16|| norm_fn_mod26 == 24 )
+ − {
+ − // FACCH: Check A_FD information block.
+ − if(emr_params->facch_present == TRUE)
+ − {
+ − // FACCH correctly decoded
+ − if(emr_params->facch_fire1 == FALSE)
+ − {
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ −
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ −
+ − if((channel_mode == SIG_ONLY_MODE))
+ − // accumulation of correctly decoded blocks excluding SACCH
+ − // and SID frames FACCH only for sig only mode
+ − l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+ − } //if(fire1 == FALSE)
+ − } //if(facch_present ==....)
+ − else
+ − {
+ − // No Facch at this positions 7,16,24
+ − if (b_blud == TRUE)
+ − {
+ − if(bfi == FALSE)
+ − {
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[7] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[4] ;
+ −
+ − //as per standard 05.08 section 8.3
+ − //sid_present can become true only at (fn modulo 26) == 6
+ − //sid_present will be false at all other points
+ −
+ − if(sid_present == FALSE)
+ − // accumulation of correctly decoded blocks excluding SACCH
+ − // FACCH and SID frames
+ − l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+ − } // if(bfi == FALSE)
+ − } // if (b_blud == TRUE)
+ − } // else facch_present
+ − } //if(norm_fn_report_mod26 == 7 || norm_fn_report_mod26 == 16|| norm_fn_report_mod26 == 24 )
+ − else
+ − {
+ − //norm_fn_report_mod26 == 3 || norm_fn_report_mod26 == 11|| norm_fn_report_mod26 == 20
+ − if (b_blud == TRUE)
+ − {
+ − if(bfi == FALSE)
+ − {
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[7] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[4] ;
+ −
+ − //as per standard 05.08 section 8.3
+ − //sid_present can become true only at (fn modulo 26) == 6
+ − //sid_present will be false at all other points
+ −
+ − if(sid_present == FALSE)
+ − // accumulation of correctly decoded blocks excluding SACCH
+ − // FACCH and SID frames
+ − l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+ − } //if(bfi == FALSE)
+ − } // if (b_blud == TRUE)
+ − } //else
+ − }//task == TCHTH.....
+ −
+ − // SACCH of TCH
+ − if((task == TCHA))
+ − {
+ − //unconditionnal accumulation of rxlev_val
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas++;
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += rxlev;
+ − if(l1s.actual_time.fn_in_report == 91)
+ − {
+ − // Set detection flag.
+ − if(emr_params->a_cd_fire1 == FALSE)
+ − {
+ − // rec 05.08 8.2.3: BEP value need to be accumulated on correctly received blocks
+ − // rec 05.08 8.4.8.2 : for SACCH of TCH, no accumulation for CV_BEP and nbr_rcvd_blocks
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ − } // if(fire1 == FALSE)
+ − } // if(l1s.actual_time.fn_in_report == 91)
+ − } // // SACCH of TCH
+ −
+ − // SDCCH and SACCH of SDCCH
+ − if (((task == DDL) || (task == ADL)) && (burst_id == BURST_4))
+ − {
+ − //unconditional accumulation of Rxlev_val
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ −
+ − // rec 05.08 8.2.3: in SDCCH, BEP value need to be accumulated on correctly received blocks
+ − if(emr_params->a_cd_fire1 == FALSE)
+ − {
+ − l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ − }
+ − } // SDCCH
+ −
+ − //AMR FS
+ − #if (AMR == 1)
+ − if((task == TCHTF) &&
+ − (channel_mode == TCH_AFS_MODE) &&
+ − (l1s.actual_time.fn_mod13_mod4 == 0))
+ − {
+ − if(emr_params->amr_facch_present == TRUE)
+ − {
+ − // FACCH present
+ − // FACCH correctly decoded ?
+ − if(emr_params->amr_facch_fire1 == FALSE)
+ − {
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ −
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ − } // if(fire1 == FALSE)
+ − } // if(facch_present == TRUE)
+ − else
+ − {
+ − // NOT FACCH
+ − if ((emr_params->b_ratscch_blud == TRUE) && (emr_params->ratscch_rxtype == RATSCCH_GOOD))
+ − {
+ − //RATSCCH correctly decoded
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ −
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ − } // if(b_ratscch_blud == TRUE)
+ − else if(emr_params->a_dd_0_blud == TRUE)
+ − {
+ − // Good speech frame.
+ − if((emr_params->amr_rx_type_sub0 == SPEECH_GOOD) ||
+ − (emr_params->amr_rx_type_sub0 == SPEECH_DEGRADED) ||
+ − (emr_params->amr_rx_type_sub0 == SID_UPDATE))
+ − {
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc += cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ −
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ −
+ − if ((emr_params->amr_rx_type_sub0 == SPEECH_GOOD) || (emr_params->amr_rx_type_sub0 == SPEECH_DEGRADED))
+ − //Number of correctly decoded blocks excluding SACCH FACCH RATSCCH and SID frames.
+ − l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+ − } // if((rx_type == SPEECH_GOOD) || (rx_type == SID_UPDATE))
+ − } // else if(b_blud == TRUE)
+ − } // else of if(facch_present == TRUE)
+ − } //AMR FS
+ −
+ − //AMR HS
+ − //TCH AHS
+ − if((task == TCHTH) &&
+ − (channel_mode == TCH_AHS_MODE)&&
+ − (normalised_fn_mod13_mod4 == 3))
+ − {
+ − UWORD8 norm_fn_mod26;
+ − subchannel = emr_params->subchannel;
+ −
+ − if (subchannel == 0)
+ − {
+ − // Load the bit to check if the block is valid
+ − b_blud = emr_params->a_dd_0_blud;
+ − rx_type = emr_params->amr_rx_type_sub0;
+ − }
+ − else // subchannel 1
+ − {
+ − // Load the bit to check if the block is valid
+ − b_blud = emr_params->a_dd_1_blud;
+ − rx_type = emr_params->amr_rx_type_sub1;
+ − }
+ −
+ − norm_fn_mod26 = (l1s.actual_time.fn - subchannel +26) % 26;
+ −
+ − if(norm_fn_mod26 == 7 ||
+ − norm_fn_mod26 == 16||
+ − norm_fn_mod26 == 24 )
+ − {
+ − // FACCH: Check A_FD information block.
+ − if(emr_params->amr_facch_present == TRUE)
+ − {
+ − // FACCH present
+ − // FACCH correctly decoded ?
+ − if(emr_params->amr_facch_fire1 == FALSE)
+ − {
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc +=mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc +=cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ −
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ − } // if(fire1 == FALSE)
+ − } // if(facch_present == TRUE)
+ − else
+ − {
+ − // NOT FACCH
+ − // Load the bit to check if the block is a RATSCCH in caseof rx_type = NO_DATA
+ − //In half rate, there are 2 consecutive frames called RATSCCH_MARKER and
+ − //RATSCCH_DATA, MARKER doesn't contain any CRC. So we cannot make a decision
+ − //whether RATSCCH_MARKER is correctly decoded. Hence ratscch_rxtype_prev
+ − //is not valid. Hence the inner check has to be based only on ratscch_rxtype.
+ − //ratscch_rxtype is updated based on the CRC of RATSCCH_DATA.
+ − //The following are the decisions on the outer check "if (b_ratscch_blud == TRUE)....
+ − //b_ratscch_blud is updated based on RATSCCH_DATA. Hence it is a valid check
+ − //b_ratscch_blud_prev would have been accumulated based on RATSCCH_MARKER.
+ − //The assumption here is that when RATSCCH_MARKER is detected, the b_blud bit of
+ − //a_ratscch_dl will be updated.
+ −
+ − if ( ((emr_params->b_ratscch_blud == TRUE) && (emr_params->ratscch_rxtype == RATSCCH_GOOD)) ||
+ − ((b_blud==TRUE) && (rx_type == SID_UPDATE)) ||
+ − ((b_blud == TRUE)&&(rx_type == SPEECH_DEGRADED)) ||
+ − ((b_blud == TRUE)&&(rx_type == SPEECH_GOOD)) )
+ − {
+ − //RATSCCH or SID Update or Speech block correctly decoded, increment the counter
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc +=mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc +=cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ −
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc +=last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ − if (((rx_type == SPEECH_GOOD) || (rx_type == SPEECH_DEGRADED)) && (emr_params->ratscch_rxtype != RATSCCH_GOOD))
+ − l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+ − }
+ − } // else part of if(facch_present == TRUE)
+ − }//fnmod26 == 7||16 || 24
+ − else
+ − {
+ − //if (norm_fn_mod26 ==3 || norm_fn_mod26 == 11 ||
+ − //norm_fn_mod26 == 20)
+ −
+ − if ( ((emr_params->b_ratscch_blud == TRUE) && (emr_params->ratscch_rxtype == RATSCCH_GOOD)) ||
+ − ((b_blud==TRUE) && (rx_type == SID_UPDATE)) ||
+ − ((b_blud == TRUE)&&(rx_type == SPEECH_DEGRADED)) ||
+ − ((b_blud == TRUE)&&(rx_type == SPEECH_GOOD)) )
+ − {
+ − //RATSCCH or SID Update or Speech block correctly decoded, increment the counter
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+ −
+ − // Accumulate BEP
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc +=mean_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc +=cv_bep;
+ − l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+ − l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+ −
+ − //accumulation of the correctly decoded block
+ − l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc +=last_corr_decoded_burst[4] +
+ − last_corr_decoded_burst[5] +
+ − last_corr_decoded_burst[6] +
+ − last_corr_decoded_burst[7];
+ − if (((rx_type == SPEECH_GOOD) || (rx_type == SPEECH_DEGRADED)) && (emr_params->ratscch_rxtype != RATSCCH_GOOD))
+ − l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+ − }
+ − } //else fn = 3,11,20
+ − }//task == TCHTH.....
+ − #endif //(AMR == 1)
+ − }
+ − #endif //FF_EMR
+ − #else //REL99
+ −
+ − void l1s_read_dedic_scell_meas(UWORD8 input_level, UWORD8 sub_flag)
+ − {
+ − WORD16 rxlev = l1s_encode_rxlev(input_level);
+ −
+ − // Measurement must be rejected if channel is hopping, hopped on
+ − // the beacon frequency and PWRC is TRUE (see GSM05.08, $8.1.3).
+ − if(!((l1a_l1s_com.dedic_set.pwrc == TRUE) &&
+ − (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->chan_sel.h == TRUE) &&
+ − (l1a_l1s_com.dedic_set.radio_freq_dd == l1a_l1s_com.Scell_info.radio_freq)))
+ − {
+ − // Add to FULL set meas.
+ − l1a_l1s_com.Scell_info.meas.nbr_meas++;
+ − l1a_l1s_com.Scell_info.meas.acc += rxlev;
+ −
+ − if(sub_flag == TRUE)
+ − {
+ − // Add to SUB set meas.
+ − l1a_l1s_com.Smeas_dedic.nbr_meas_sub++;
+ − l1a_l1s_com.Smeas_dedic.acc_sub += rxlev;
+ − }
+ − }
+ − }
+ − #endif //REL99
+ − /*-------------------------------------------------------*/
+ − /* l1s_dedic_reporting() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − void l1s_dedic_reporting()
+ − {
+ − xSignalHeaderRec *msg;
+ − UWORD8 i;
+ − UWORD32 nbr_carrier = l1a_l1s_com.ba_list.nbr_carrier;
+ −
+ − // Allocate L1C_MEAS_DONE message...
+ − msg = os_alloc_sig(sizeof(T_MPHC_MEAS_REPORT));
+ − DEBUGMSG(status,NU_ALLOC_ERR)
+ − msg->SignalCode = L1C_MEAS_DONE;
+ −
+ − // Fill miscelaneous parameters
+ − //=============================
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->ba_id = l1a_l1s_com.ba_list.ba_id;
+ −
+ − //timing_advance...
+ − //txpwr...
+ − //meas_valid...
+ −
+ − // Fill msg for Neighbor Cells
+ − //============================
+ −
+ − for(i=0;i<nbr_carrier;i++)
+ − {
+ − T_MEAS_INFO *ba_ptr = &l1a_l1s_com.ba_list.A[i];
+ −
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->ncell_meas.A[i].bcch_freq = ba_ptr->radio_freq;
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->ncell_meas.A[i].rxlev_acc = ba_ptr->acc;
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->ncell_meas.A[i].rxlev_nbr_meas = ba_ptr->nbr_meas;
+ −
+ − // Reset BA.
+ − ba_ptr->acc = 0;
+ − ba_ptr->nbr_meas = 0;
+ − }
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->no_of_ncell_meas = nbr_carrier;
+ −
+ − // Fill msg for Serving Cell
+ − //==========================
+ −
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxlev_full_acc = l1a_l1s_com.Scell_info.meas.acc;
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxlev_full_nbr_meas = l1a_l1s_com.Scell_info.meas.nbr_meas;
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxlev_sub_acc = l1a_l1s_com.Smeas_dedic.acc_sub;
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxlev_sub_nbr_meas = l1a_l1s_com.Smeas_dedic.nbr_meas_sub;
+ −
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxqual_full_acc_errors = l1a_l1s_com.Smeas_dedic.qual_acc_full;
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxqual_full_nbr_bits = l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full;
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxqual_sub_acc_errors = l1a_l1s_com.Smeas_dedic.qual_acc_sub;
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxqual_sub_nbr_bits = l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub;
+ −
+ − #if REL99
+ − #if FF_EMR
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxlev_val_acc = l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc;
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxlev_val_nbr_meas = l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas;
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->nbr_rcvd_blocks = l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks;
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->mean_bep_block_acc = l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc;
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->cv_bep_block_acc = l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc;
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->mean_bep_block_num = l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num;
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->cv_bep_block_num = l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num;
+ − #endif
+ − #endif
+ −
+ − if(l1a_l1s_com.dedic_set.aset->dtx_allowed == TRUE)
+ − // Set "dtx_used" flag according to DSP transmit report result only if
+ − // DTX is allowed.
+ − {
+ − if(l1a_l1s_com.Smeas_dedic.dtx_used > 0)
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->dtx_used = TRUE;
+ − // Set the dtx_used flag in the case of TCHF/ no signaling
+ − else if ((l1a_l1s_com.dedic_set.aset->chan1.mode == SIG_ONLY_MODE)
+ − &&(l1a_l1s_com.dedic_set.aset->chan1.desc.channel_type==TCH_F))
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->dtx_used = TRUE;
+ − else
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->dtx_used = FALSE;
+ − }
+ − else
+ − {
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->dtx_used = FALSE;
+ − }
+ −
+ − // Reset Serving Cell measurement variables.
+ − l1s_reset_dedic_serving_meas();
+ −
+ −
+ − // Give miscellaneous info to L3 (just for indication/debug).
+ − //===========================================================
+ −
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->timing_advance = l1a_l1s_com.dedic_set.aset->timing_advance;
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->txpwr_used = l1s.reported_txpwr;
+ −
+ − #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->facch_dl_count = trace_info.facch_dl_count;
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->facch_ul_count = trace_info.facch_ul_count;
+ − #if (FF_REPEATED_DL_FACCH == 1)
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->facch_dl_combined_good_count = trace_info.facch_dl_combined_good_count; /* No of good blocks after combining */
+ − ((T_MPHC_MEAS_REPORT*)(msg->SigP))->facch_dl_repetition_block_count = trace_info.facch_dl_repetition_block_count;
+ − #endif/* (FF_REPEATED_DL_FACCH == 1) */
+ − trace_info.facch_dl_fail_count_trace = trace_info.facch_dl_fail_count;
+ − trace_info.facch_dl_count = 0;
+ − trace_info.facch_ul_count = 0;
+ − trace_info.facch_dl_fail_count = 0;
+ − #if ( FF_REPEATED_DL_FACCH == 1 ) /* Reseting the values */
+ − trace_info.facch_dl_combined_good_count = 0;
+ − trace_info.facch_dl_repetition_block_count = 0;
+ − #endif/* (FF_REPEATED_DL_FACCH == 1) */
+ − #endif
+ −
+ − // send L1C_MEAS_DONE message...
+ − os_send_sig(msg, L1C1_QUEUE);
+ − DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+ − }
+ −
+ − #if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_read_fb() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : this function sends L1C_FB_INFO to L1A*/
+ − /*-------------------------------------------------------*/
+ − void l1s_read_fb(UWORD8 task, UWORD32 fb_flag, UWORD32 toa, UWORD32 attempt,
+ − UWORD32 pm, UWORD32 angle, UWORD32 snr)
+ − {
+ − xSignalHeaderRec *msg;
+ − WORD32 modif_toa = 0;
+ − WORD32 ntdma;
+ − UWORD32 fn_offset;
+ −
+ − // For detail of the here below equation cf. BUG1558
+ − #define MAX_TOA_FOR_SB (D_NSUBB_DEDIC*48)+DL_ABB_DELAY/4-(SB_BURST_DURATION+DL_ABB_DELAY+SB_MARGIN)/4-2
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dspres(dltsk_trace[task].name);
+ − #endif
+ −
+ − #if (TRACE_TYPE!=0)
+ − switch(task)
+ − {
+ − case FBNEW: trace_fct(CST_L1S_READ_FB, l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].radio_freq);break;
+ − case FB51: trace_fct(CST_L1S_READ_FB51, l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].radio_freq);break;
+ − case FB26: trace_fct(CST_L1S_READ_FB26, l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].radio_freq);break;
+ − default: trace_fct(CST_UNKNOWN_FB, l1a_l1s_com.nsync.list[0].radio_freq);break;
+ − }
+ − #endif
+ −
+ − if(fb_flag == TRUE)
+ − {
+ − switch (task)
+ − {
+ − case FBNEW:
+ − case FB51:
+ − // Compute NTDMA & TOA taking into account the 23 bit guard for next SB receive window.
+ − {
+ − modif_toa = toa - (SB_MARGIN/4); // Rem: unit is "BIT".
+ − }
+ − break;
+ −
+ − case FB26:
+ − // Compute TOA taking into account the 23 bit guard for next SB receive window
+ − // and the time diff. between a the fb search and a normal serving RX slot..
+ − // Rem: TOA cannot be less than "SB_MARGIN/4".
+ − {
+ − // Saturate TOA to MAX_TOA_FOR_SB since it is the last position compatible with the
+ − // SB26 tpu programming. MAX_TOA_FOR_SB + 1 would reject the TCHT/frame0 one frame later due
+ − // to an overlap of TPU scenarios.
+ − if(toa >= MAX_TOA_FOR_SB) toa = MAX_TOA_FOR_SB;
+ −
+ − modif_toa = toa + ((l1_config.params.fb26_anchoring_time + PROVISION_TIME - START_RX_FB)/4) - (SB_MARGIN/4); // Rem: unit is "BIT".
+ − }
+ − break;
+ − } // End of switch.
+ −
+ − if(modif_toa < 0)
+ − {
+ − modif_toa = (modif_toa + (TPU_CLOCK_RANGE/4)) * 4; // Unit is changed from bit to qbit.
+ − ntdma = - 1;
+ − }
+ − else
+ − {
+ − ntdma = modif_toa / (TPU_CLOCK_RANGE/4);
+ − modif_toa = (modif_toa - ntdma * (TPU_CLOCK_RANGE/4)) * 4; // Unit is changed from bit to qbit.
+ − }
+ −
+ − switch (task)
+ − {
+ − case FBNEW:
+ − // Compute NTDMA & TOA taking into account the 23 bit guard for next SB receive window.
+ − {
+ − // "fn_offset" loaded with serving frame number corresponding to FB.
+ − // Keep a %51 format to prepare SB scheduling.
+ − fn_offset = (l1s.actual_time.fn - attempt + ntdma + MAX_FN) % 51;
+ − }
+ − break;
+ −
+ − case FB51:
+ − // Compute NTDMA & TOA taking into account the 23 bit guard for next SB receive window.
+ − {
+ − // "fn_offset" loaded with serving frame number corresponding to FB.
+ − // Keep a full frame number to allow scheduling of SB, 2 MF51 later.
+ − fn_offset = (l1s.actual_time.fn - attempt + ntdma + MAX_FN) % MAX_FN;
+ − }
+ − break;
+ −
+ − case FB26:
+ − {
+ − // "fn_offset" loaded with serving frame number corresponding to CTL(SB26).
+ − fn_offset = (l1s.actual_time.fn + 52 - 3) % MAX_FN;
+ −
+ − if(ntdma == 1) // 2nd frame...
+ − l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].sb26_offset = 1;
+ − else
+ − l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].sb26_offset = 0;
+ − }
+ − break;
+ − } // End of switch.
+ −
+ − } // End if.
+ −
+ − // Store TOA and FN offset in neighbor cell structure.
+ − l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].time_alignmt = modif_toa;
+ − l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].fn_offset = fn_offset;
+ −
+ − // Create message T_L1C_FB_INFO.
+ − msg = os_alloc_sig(sizeof(T_L1C_FB_INFO));
+ − DEBUGMSG(status,NU_ALLOC_ERR)
+ − msg->SignalCode = L1C_FB_INFO;
+ −
+ − // Fill msg fields.
+ − ((T_L1C_FB_INFO *) (msg->SigP))->fb_flag = fb_flag;
+ − ((T_L1C_FB_INFO *) (msg->SigP))->ntdma = ntdma;
+ − ((T_L1C_FB_INFO *) (msg->SigP))->neigh_id = l1a_l1s_com.nsync.active_fb_id;
+ − // Debug info or testmode
+ − ((T_L1C_FB_INFO *) (msg->SigP))->pm = pm;
+ − ((T_L1C_FB_INFO*)(msg->SigP))->toa = toa;
+ − ((T_L1C_FB_INFO*)(msg->SigP))->angle = angle;
+ − ((T_L1C_FB_INFO*)(msg->SigP))->snr = snr;
+ − ((T_L1C_FB_INFO *) (msg->SigP))->radio_freq = l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].radio_freq;
+ −
+ − os_send_sig(msg, L1C1_QUEUE);
+ − DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+ − }
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+ − #endif // MOVE_IN_INTERNAL_RAM
+ −
+ − #if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_read_sb() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : this function sends L1C_SB_INFO to L1A*/
+ − /*-------------------------------------------------------*/
+ − void l1s_read_sb(UWORD8 task, UWORD32 flag, API *data, UWORD32 toa, UWORD8 attempt,
+ − UWORD32 pm, UWORD32 angle, UWORD32 snr)
+ − {
+ − xSignalHeaderRec *msg;
+ − UWORD8 bsic=0;
+ − UWORD32 sb;
+ − WORD32 modif_toa = 0;
+ − UWORD32 fn_offset = 0;
+ − WORD32 time_alignmt = 0;
+ − T_NCELL_SINGLE *cell_ptr = NULL; //omaps00090550 NULL;
+ − UWORD32 SignalCode=0;
+ − UWORD8 fn_delay = 2; // SB result read with 2 frames delay.
+ − UWORD8 neigh_id=0;
+ − UWORD32 fn;
+ −
+ − switch(task)
+ − {
+ − case SB2 :
+ − case SB51 :
+ − case SB26 :
+ − // Get Neighbour cell ptr.
+ − cell_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sb_id];
+ − neigh_id = l1a_l1s_com.nsync.active_sb_id;
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_READ_SB, cell_ptr->radio_freq);
+ − #endif
+ −
+ − SignalCode = L1C_SB_INFO;
+ − if(task == SB26) fn_delay = 3 - l1a_l1s_com.nsync.list[neigh_id].sb26_offset;
+ − break;
+ −
+ − case SBCONF :
+ − case SBCNF51 :
+ − case SBCNF26 :
+ − // Get Neighbour cell ptr.
+ − cell_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sbconf_id];
+ − neigh_id = l1a_l1s_com.nsync.active_sbconf_id;
+ −
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_READ_SBCONF, cell_ptr->radio_freq);
+ − #endif
+ −
+ − SignalCode = L1C_SBCONF_INFO;
+ − if(task == SBCNF26) fn_delay = 3 - l1a_l1s_com.nsync.list[neigh_id].sb26_offset;
+ − break;
+ − }
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dspres(dltsk_trace[task].name);
+ − #endif
+ −
+ − // Compute NTDMA & TOA taking into account the 23 bit guard for next SB receive window.
+ − modif_toa = (toa - (SB_MARGIN/4)) * 4; // Rem: unit is "QBIT".
+ −
+ − // Read SB content,.
+ − sb = data[0] & 0xffff | ((data[1] & 0xffff) << 16);
+ −
+ − if (flag == TRUE)
+ − // SB has been found...
+ − // We synchronized with a NEIGHBOUR cell.
+ − {
+ − UWORD32 t1, t2, t3, t3p;
+ −
+ − // extract BSIC, T1, T2, T3. Compute FN.
+ − // bsic contains NCC & BCC (GSM05.02, p9)
+ − bsic = (UWORD8) ((sb & 0x000000fc) >> 2);
+ −
+ − t1 = ((sb & 0x00800000) >> 23 | // t1 low
+ − (sb & 0x0000ff00) >> 7 | // t1 midle
+ − (sb & 0x00000003) << 9); // t1 high
+ − t2 = (sb & 0x007c0000) >> 18;
+ − t3p = ((sb & 0x01000000) >> 24 | // t3p low
+ − (sb & 0x00030000) >> 15); // t3p high
+ − t3 = (10*(t3p) +1);
+ − fn = (51 * ((t3 - t2 + 26) % 26) + t3 + (26 * 51 * t1));
+ −
+ − // Due to pipeline effect (CTRL.WORK.WORK.READ), sb content is taken into account
+ − // "fn_delay" TDMA later: that's why we use "fn + fn_delay..." in the offset computation.
+ − //
+ − // NEIGHBOUR DOMAIN:
+ − // -----------------
+ − // | |<----- 1 TDMA ----->| SB | |
+ − // | | |XXXX | |
+ − // | | | | |
+ − // | | | FN_neighbour(SB) | FN_neighbour(SB)+1 | FN_neighbour(SB)+2
+ − // | | | | |
+ − // offset |
+ − // + |
+ − // BOB |
+ − // |<----------->|
+ − // MS DOMAIN: |
+ − // ---------- | | | |
+ − // | CTRL | WORK | WORK | READ |
+ − // | | | | |
+ − //
+ − // offset = FN_neighbour(SB)+ fn_delay - FN_serving(READ).
+ − // Bob: fine timing difference between the Neighbour timing and the MS internal timing.
+ − //
+ − fn_offset = (fn + fn_delay + MAX_FN - l1s.actual_time.fn) % MAX_FN;
+ −
+ − // "time_alignmt" must be corrected (use "modif_toa" from the SB read).
+ − // Check that "time_alignmt" do not become bigger than "TPU_CLOCK_RANGE".
+ − // If so, "fn_offset" must be decremented.
+ − time_alignmt = cell_ptr->time_alignmt + modif_toa;
+ − if(time_alignmt >= TPU_CLOCK_RANGE)
+ − {
+ − time_alignmt -= TPU_CLOCK_RANGE; // qbp for sim. Normal value is 1250;
+ − fn_offset -= 1; // WARNING....to be checked!!!!!!
+ − }
+ − else
+ − if(time_alignmt < 0)
+ − {
+ − time_alignmt += TPU_CLOCK_RANGE; // qbp for sim. Normal value is 1250;
+ − fn_offset += 1; // WARNING....to be checked!!!!!!
+ − }
+ − }
+ −
+ − #if L1_RECOVERY
+ − if(flag)
+ − {
+ − // recovery flag is reseted because the system works fine
+ − // this check is performed in all modes.
+ − l1a_l1s_com.recovery_flag = FALSE;
+ −
+ − // Reset error flags and counter
+ − l1s.recovery.frame_count = 0;
+ − }
+ − #endif
+ −
+ − // In all mode send result message to L1 Async.
+ − 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 = flag;
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->radio_freq = cell_ptr->radio_freq;
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->bsic = bsic;
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->fn_offset = fn_offset;
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->time_alignmt = time_alignmt;
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->neigh_id = neigh_id;
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->attempt = attempt;
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->pm = pm;
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->toa = toa;
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->angle = angle;
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->snr = snr;
+ −
+ −
+ − #if (L1_EOTD == 1)
+ − // In EOTD mode read additional results
+ − if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
+ − {
+ − UWORD8 i;
+ − WORD16 d_eotd_first;
+ − WORD16 d_eotd_max;
+ − UWORD32 d_eotd_nrj;
+ − API *data = &(l1s_dsp_com.dsp_ndb_ptr->a_eotd_crosscor[0]);
+ − UWORD32 fn_sb_neigh;
+ −
+ − d_eotd_first = l1s_dsp_com.dsp_ndb_ptr->d_eotd_first & 0xffff;
+ −
+ − d_eotd_max = l1s_dsp_com.dsp_ndb_ptr->d_eotd_max & 0xffff;
+ −
+ − fn_sb_neigh = (l1s.actual_time.fn - fn_delay + MAX_FN) % MAX_FN;
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->fn_sb_neigh = fn_sb_neigh;
+ −
+ − d_eotd_nrj = (l1s_dsp_com.dsp_ndb_ptr->d_eotd_nrj_low & 0xffff) |
+ − ((l1s_dsp_com.dsp_ndb_ptr->d_eotd_nrj_high & 0x00ff) << 16);
+ −
+ − // L1 SW :
+ − // CPS Cursor expects the accumulated signal level of the cross
+ − // correlation (d_eotd_nrj) to be 16bit format. The DSP reports
+ − // it as 24bit format (lsb aligned in a 32bit word).
+ − // We scale the DSP result by right shifting by 8, hence preserving
+ − // the MSBs
+ −
+ − d_eotd_nrj >>= 8;
+ −
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->eotd_data_valid = TRUE;
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->d_eotd_first = d_eotd_first;
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->d_eotd_max = d_eotd_max;
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->d_eotd_nrj = d_eotd_nrj;
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->fn_in_SB = fn;
+ − for (i=0; i<18; i++)
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->a_eotd_crosscor[i] = data[i] & 0xffff;;
+ −
+ − if(task == SBCNF26)
+ − {
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->toa_correction =
+ − l1a_l1s_com.nsync.eotd_cache_toa_tracking;
+ − }
+ − else
+ − {
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->toa_correction = 0;
+ − }
+ −
+ − }
+ − else
+ − ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->eotd_data_valid = FALSE;
+ − #endif
+ −
+ −
+ −
+ − os_send_sig(msg, L1C1_QUEUE);
+ − DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+ − }
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+ − #endif // MOVE_IN_INTERNAL_RAM
+ −
+ − #if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_read_fbsb() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : sends L1C_FBSB_INFO to L1A */
+ − /*-------------------------------------------------------*/
+ − #if ((REL99 == 1) && (FF_BHO == 1))
+ − void l1s_read_fbsb(UWORD8 task, UWORD8 attempt, BOOL fb_flag, BOOL sb_flag, API *data, UWORD32 toa, UWORD32 pm, UWORD32 angle, UWORD32 snr)
+ − {
+ − xSignalHeaderRec *msg;
+ − UWORD8 bsic = 0;
+ − UWORD32 fn_offset = 0;
+ − UWORD32 time_alignmt = 0;
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dspres(dltsk_trace[task].name);
+ − #endif
+ −
+ − #if (TRACE_TYPE!=0)
+ − // trace_fct(CST_L1S_READ_FBSB, l1a_l1s_com.nsync_fbsb.radio_freq);
+ − #endif
+ −
+ − if ((fb_flag == TRUE) && (sb_flag == TRUE))
+ − {
+ − UWORD32 toa_qbit, sb, fn, fn2, t1, t2, t3, t3p;
+ − UWORD8 ntdma;
+ −
+ − // Read SB content,.
+ − sb = data[0] & 0xffff | ((data[1] & 0xffff) << 16);
+ −
+ − // extract BSIC, T1, T2, T3. Compute FN.
+ − // bsic contains NCC & BCC (GSM05.02, p9)
+ − bsic = (UWORD8) ((sb & 0x000000fc) >> 2);
+ −
+ − t1 = ((sb & 0x00800000) >> 23 | // t1 low
+ − (sb & 0x0000ff00) >> 7 | // t1 midle
+ − (sb & 0x00000003) << 9); // t1 high
+ − t2 = (sb & 0x007c0000) >> 18;
+ − t3p = ((sb & 0x01000000) >> 24 | // t3p low
+ − (sb & 0x00030000) >> 15); // t3p high
+ − t3 = (10*(t3p) +1);
+ − fn = (51 * ((t3 - t2 + 26) % 26) + t3 + (26 * 51 * t1));
+ −
+ − // _|-----------------------------------|___ : TPU WINDOW
+ − // |FB| |SB|
+ − // _|---------------->|--------->|->|
+ − // toa_fb 1 frame toa_sb
+ − //
+ − // we also need to take into account the 23 bit guard for SB receive window.
+ −
+ − toa_qbit = (l1a_l1s_com.nsync_fbsb.fb_toa + toa) * 4 + TPU_CLOCK_RANGE - SB_MARGIN;
+ −
+ − ntdma = toa_qbit / TPU_CLOCK_RANGE;
+ −
+ − fn_offset = (fn - l1s.actual_time.fn + attempt - ntdma + (2 * MAX_FN))% MAX_FN;
+ −
+ − time_alignmt = toa_qbit - (ntdma * TPU_CLOCK_RANGE);
+ − }
+ −
+ − // Create message T_L1C_FBSB_INFO.
+ − msg = os_alloc_sig(sizeof(T_L1C_FB_INFO));
+ − DEBUGMSG(status,NU_ALLOC_ERR)
+ − msg->SignalCode = L1C_FBSB_INFO;
+ −
+ − // Fill msg fields.
+ − ((T_L1C_FBSB_INFO *) (msg->SigP))->fb_flag = fb_flag;
+ − ((T_L1C_FBSB_INFO *) (msg->SigP))->sb_flag = sb_flag;
+ − ((T_L1C_FBSB_INFO *) (msg->SigP))->bsic = bsic;
+ − ((T_L1C_FBSB_INFO *) (msg->SigP))->fn_offset = fn_offset;
+ − ((T_L1C_FBSB_INFO *) (msg->SigP))->time_alignmt = time_alignmt;
+ − ((T_L1C_FBSB_INFO *) (msg->SigP))->pm = pm;
+ − ((T_L1C_FBSB_INFO *) (msg->SigP))->toa = toa;
+ − ((T_L1C_FBSB_INFO *) (msg->SigP))->angle = angle;
+ − ((T_L1C_FBSB_INFO *) (msg->SigP))->snr = snr;
+ −
+ −
+ − os_send_sig(msg, L1C1_QUEUE);
+ − DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+ − }
+ − #endif // #if ((REL99 == 1) && (FF_BHO == 1))
+ − //#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+ − #endif // MOVE_IN_INTERNAL_RAM
+ −
+ − #if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM !=0)) // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM enabled
+ − //#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_START // KEEP IN EXTERNAL MEM otherwise
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_read_l3frm() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : reads NB data */
+ − /* and formate MPHC_DATA_IND message */
+ − /*-------------------------------------------------------*/
+ − void l1s_read_l3frm(UWORD8 pwr_level, API *info_address, UWORD32 task_rx)
+ − {
+ − xSignalHeaderRec *msg;
+ − UWORD32 i,j;
+ − UWORD32 word32;
+ − UWORD32 rx_fail_flag;
+ − //OMAPS00090550 UWORD32 b_fire0;
+ − UWORD32 b_fire1;
+ − UWORD8 tc = l1s.actual_time.tc; // Default: tc loaded with current serving TC.
+ − UWORD16 radio_freq = l1a_l1s_com.Scell_info.radio_freq; // Default: radio_freq load with serving cell
+ −
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dspres(dltsk_trace[task_rx].name);
+ − #endif
+ −
+ − // Allocate result message.
+ −
+ − #if (GSM_IDLE_RAM == 1) // GPF not modified for GSM_IDLE_RAM -> enable Traffic Controller in L1S
+ − if (!READ_TRAFFIC_CONT_STATE)
+ − CSMI_TrafficControllerOn();
+ − #endif
+ −
+ − msg = os_alloc_sig(sizeof(T_MPHC_DATA_IND));
+ − DEBUGMSG(status,NU_ALLOC_ERR)
+ −
+ − switch(task_rx)
+ − {
+ − case NP:
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_READ_L3FRM__NP, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − // Fill msg signal code and L2 channel.
+ − msg->SignalCode = L1C_NP_INFO;
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_PCH;
+ − break;
+ −
+ − case EP:
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_READ_L3FRM__EP, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − // Fill msg signal code and L2 channel.
+ − msg->SignalCode = L1C_EP_INFO;
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_EPCH;
+ − break;
+ −
+ − case NBCCHS:
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_READ_L3FRM__NBCCHS, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − // Fill msg signal code and L2 channel.
+ − msg->SignalCode = L1C_BCCHS_INFO;
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_NBCCH;
+ − break;
+ −
+ − case EBCCHS:
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_READ_L3FRM__EBCCHS, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − // Fill msg signal code and L2 channel.
+ − msg->SignalCode = L1C_BCCHS_INFO;
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_EBCCH;
+ − break;
+ −
+ − case BCCHN:
+ − #if L1_GPRS
+ − case BCCHN_TRAN:
+ − #endif
+ − case BCCHN_TOP:
+ − #if (TRACE_TYPE!=0)
+ − if (task_rx == BCCHN)
+ − trace_fct(CST_L1S_READ_L3FRM__BCCHN, l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_norm].radio_freq);
+ − else // BCCHN_TRAN and BCCHN_TOP tasks
+ − trace_fct(CST_L1S_READ_L3FRM__BCCHN, l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_top].radio_freq);
+ − #endif
+ −
+ − // Fill msg signal code, L2 channel and get neighbour TC.
+ − msg->SignalCode = L1C_BCCHN_INFO;
+ −
+ − // Save neighbour ID.
+ − // With TC and Neighbour ID, L1A can manage the remaining BCCH requests.
+ − if (task_rx == BCCHN)
+ − {
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->neigh_id = l1a_l1s_com.bcchn.active_neigh_id_norm;
+ − tc = l1a_l1s_com.bcchn.active_neigh_tc_norm;
+ − radio_freq = l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_norm].radio_freq;
+ − }
+ − else // BCCHN_TRAN and BCCHN_TOP tasks
+ − {
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->neigh_id = l1a_l1s_com.bcchn.active_neigh_id_top;
+ − tc = l1a_l1s_com.bcchn.active_neigh_tc_top;
+ − radio_freq = l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_top].radio_freq;
+ − }
+ −
+ − if(tc >= 8)
+ − {
+ − // Reading Extended BCCH.
+ − tc -= 8;
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_EBCCH;
+ − }
+ − else
+ − {
+ − // Reading Normal BCCH.
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_NBCCH;
+ − }
+ −
+ − break;
+ −
+ − case ALLC:
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_READ_L3FRM__ALLC, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − // Fill msg signal code, L2 channel and get neighbour TC.
+ − msg->SignalCode = L1C_ALLC_INFO;
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_CCCH;
+ − break;
+ −
+ − case SMSCB:
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1S_READ_L3FRM__CB, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − // Fill msg signal code, L2 channel and get neighbour TC.
+ − msg->SignalCode = L1C_CB_INFO;
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_CBCH;
+ − break;
+ −
+ − #if L1_GPRS
+ −
+ − case PNP:
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1PS_READ_L3FRM__PNP, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − // Fill msg signal code and L2 channel.
+ − msg->SignalCode = L1P_PNP_INFO;
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_PCHANNEL_PPCH;
+ − tc = l1pa_l1ps_com.pbcchs.rel_pos_to_report;
+ − break;
+ −
+ − case PEP:
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1PS_READ_L3FRM__PEP, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − // Fill msg signal code and L2 channel.
+ − msg->SignalCode = L1P_PEP_INFO;
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_PCHANNEL_PEPCH;
+ − tc = l1pa_l1ps_com.pbcchs.rel_pos_to_report;
+ − break;
+ −
+ − case PALLC:
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1PS_READ_L3FRM__PALLC, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − // Fill msg signal code and L2 channel.
+ − msg->SignalCode = L1P_PALLC_INFO;
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_PCHANNEL_PCCCH;
+ − tc = l1pa_l1ps_com.pbcchs.rel_pos_to_report;
+ − break;
+ −
+ − case PBCCHS:
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1PS_READ_L3FRM__PBCCHS, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − // Fill msg signal code and L2 channel.
+ − msg->SignalCode = L1P_PBCCHS_INFO;
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_PCHANNEL_PBCCH;
+ − tc = l1pa_l1ps_com.pbcchs.rel_pos_to_report;
+ − break;
+ −
+ − case PBCCHN_IDLE:
+ − case PBCCHN_TRAN:
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1PS_READ_L3FRM__PBCCHN, l1pa_l1ps_com.pbcchn.bcch_carrier);
+ − #endif
+ −
+ − // Fill msg signal code and L2 channel.
+ − msg->SignalCode = L1P_PBCCHN_INFO;
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_PCHANNEL_PBCCH;
+ − tc = l1pa_l1ps_com.pbcchn.relative_position;
+ − radio_freq = l1pa_l1ps_com.pbcchn.bcch_carrier;
+ − break;
+ −
+ − case SINGLE:
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1PS_READ_L3FRM__SINGLE, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − // Fill L2 channel.
+ − msg->SignalCode = L1P_PACCH_INFO;
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_PCHANNEL_PACCH;
+ − tc = l1pa_l1ps_com.pbcchs.rel_pos_to_report;
+ − break;
+ −
+ − #endif
+ −
+ − // WARNING !!! to be removed (for CBCH debugging).
+ − default:
+ − #if (TRACE_TYPE!=0)
+ − trace_fct(CST_L1PS_READ_L3FRM__UNKNOWN, l1a_l1s_com.Scell_info.radio_freq);
+ − #endif
+ −
+ − // Fill msg signal code, L2 channel and get neighbour TC.
+ − msg->SignalCode = L1C_CB_INFO;
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_CCCH;
+ − }
+ −
+ − #if L1_GPRS
+ − if (l1a_l1s_com.dsp_scheduler_mode == GSM_SCHEDULER)
+ − #endif
+ − {
+ − // Compute detection flag.
+ − //OMAPS00090550 b_fire0 = ((info_address[0] & 0xffff) & (1<<B_FIRE0)) >> B_FIRE0;
+ − b_fire1 = ((info_address[0] & 0xffff) & (1<<B_FIRE1)) >> B_FIRE1;
+ − if(b_fire1 != 1)
+ − rx_fail_flag = FALSE; // information block received successfully.
+ − else
+ − rx_fail_flag = TRUE; // information block reception failled.
+ −
+ − // Get 23 bytes info. from DSP.
+ − for (j=0, i=0; i<11; i++)
+ − {
+ − word32 = info_address[3 + i]; // Get info word, rem: skip info. header.
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_frame.A[j++] = (word32 & 0x000000ff);
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_frame.A[j++] = (word32 & 0x0000ff00) >> 8;
+ − }
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_frame.A[22] = (info_address[14] & 0x000000ff);
+ −
+ − // reset buffers and flags in NDB ...
+ − // B_FIRE1 =1, B_FIRE0 =0 , BLUD =0
+ − info_address[0] = (1<<B_FIRE1);
+ − }
+ − #if L1_GPRS
+ − else // GPRS scheduler
+ − {
+ − // Compute detection flag.
+ − rx_fail_flag = ((*info_address & 0x0100) >> 8);
+ −
+ − // Get 24 bytes info. from DSP: CS1 meaningful block is of size 12 UWORD16 data.
+ − // !!! WARNING: word32 type is for compatibility with chipset == 0.
+ − // Can be word16 if only chipset == 2 is used.
+ − for (j=0, i=0; i<12; i++)
+ − {
+ − // Data downloaded from a_dd_gprs[0][]...
+ − word32 = info_address[4 + i]; // Get info word, rem: skip info. header.
+ − #if 0 /* FreeCalypso TCS211 reconstruction */
+ − if(j<23)
+ − #endif
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_frame.A[j++] = (word32 & 0x000000ff);
+ − #if 0 /* FreeCalypso TCS211 reconstruction */
+ − if(j<23)
+ − #endif
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->l2_frame.A[j++] = (word32 & 0x0000ff00) >> 8;
+ − }
+ −
+ − // reset buffers and flags in NDB ...
+ − // reset CS_TYPE
+ − info_address[0] = CS_NONE_TYPE;
+ − }
+ − #endif
+ −
+ − // Report detection flag.
+ − if((l1s_dsp_com.dsp_db_r_ptr->d_debug & 0xffff ) != (l1s.debug_time & 0xffff )) // in case of COM error the block is false
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->error_flag = TRUE;
+ − else
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->error_flag = rx_fail_flag;
+ −
+ − // be careful: radio_freq is setted at the beging of the code and may be modified inside the "case"
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->radio_freq = radio_freq;
+ −
+ − // be careful: tc is setted at the beging of the code and may be modified inside the "case"
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->tc = tc;
+ −
+ − // convert in ETSI format and send it back to L3
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->ccch_lev = l1s_encode_rxlev(pwr_level);
+ −
+ − #if (FF_L1_FAST_DECODING == 1)
+ − // Update the fn according to the number of the last decoded burst (2, 3 or 4) in case of fast paging: alignment with a block boudary
+ − if(l1a_l1s_com.last_fast_decoding == 0)
+ − // fast decoding was not not used
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->fn = l1s.actual_time.fn;
+ − else
+ − // fast decoding done, fn is incremented up to 2 frames (if fast decoding with 2 bursts), 0 if fast decoding with 4 bursts (normal decoding)
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->fn = l1s.actual_time.fn + BURST_4 + 1 - l1a_l1s_com.last_fast_decoding;
+ − #else
+ − ((T_MPHC_DATA_IND *)(msg->SigP))->fn = l1s.actual_time.fn;
+ − #endif
+ − // send message...
+ −
+ − os_send_sig(msg, L1C1_QUEUE);
+ − DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+ − }
+ −
+ − //#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END
+ − #endif
+ − /*-------------------------------------------------------*/
+ − /* l1s_read_sacch_dl() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : reads NB data */
+ − /*-------------------------------------------------------*/
+ − void l1s_read_sacch_dl(API *info_address, UWORD32 task_rx)
+ − {
+ − xSignalHeaderRec *msg;
+ − UWORD32 i,j;
+ − UWORD32 word32;
+ − UWORD32 rx_fail_flag;
+ − //OMAPS00090550 UWORD32 b_fire0;
+ − UWORD32 b_fire1;
+ − #if (FF_REPEATED_SACCH == 1)
+ − BOOL b_joint= 0; /* The flag to read the DSP response on combining */
+ − static BOOL prevfail = 0;
+ − #endif /* (FF_REPEATED_SACCH == 1) */
+ −
+ − // Traces.
+ − #if (TRACE_TYPE==5) && FLOWCHART
+ − trace_flowchart_dspres(dltsk_trace[task_rx].name);
+ − #endif
+ −
+ − #if (TRACE_TYPE!=0)
+ − if(task_rx == ADL) trace_fct(CST_L1S_READ_SACCH_DL__ADL, l1a_l1s_com.dedic_set.radio_freq_dd);
+ − if(task_rx == TCHA) trace_fct(CST_L1S_READ_SACCH_DL__TCHA, l1a_l1s_com.dedic_set.radio_freq_dd);
+ − #endif
+ −
+ − #if (((TRACE_TYPE==1) || (TRACE_TYPE==4)) && ((FF_REPEATED_SACCH == 1)))
+ − trace_info.repeat_sacch.dl_count ++; /* It is a SACCH downlink block */
+ −
+ − #endif
+ − // Compute detection flag.
+ − //OMAPS00090550 b_fire0 = ((info_address[0] & 0xffff) & (1<<B_FIRE0)) >> B_FIRE0;
+ − b_fire1 = ((info_address[0] & 0xffff) & (1<<B_FIRE1)) >> B_FIRE1;
+ − if(b_fire1 != 1)
+ − rx_fail_flag = FALSE; // information block received successfully.
+ − else
+ − rx_fail_flag = TRUE; // information block reception failled.
+ −
+ − #if (FF_REPEATED_SACCH == 1)
+ − b_joint = (BOOL)(((info_address[0] & 0xffff) & (1<<B_JOINT)) >> B_JOINT);
+ −
+ − #endif /* (FF_REPEATED_SACCH == 1) */
+ − // Clear 1st word of header.
+ − info_address[0] = 0;
+ −
+ − #if ((TESTMODE) && ((FF_REPEATED_SACCH == 1)) )
+ − if(l1_config.repeat_sacch_enable != REPEATED_SACCH_ENABLE)
+ − {
+ − l1s.repeated_sacch.srr = 0;
+ − #if (TRACE_TYPE == 1 || TRACE_TYPE == 4)
+ − trace_info.repeat_sacch.dl_buffer_empty = TRUE;
+ − #endif /* TRACE_TYPE*/
+ − }
+ − else
+ − {
+ − #endif /* ((TESTMODE) && ((FF_REPEATED_SACCH == 1))) */
+ −
+ −
+ − #if (FF_REPEATED_SACCH == 1)
+ −
+ − if( (b_joint==TRUE) || (rx_fail_flag==TRUE ))
+ − {
+ − /* chase combining occurred or the current block was unsuccessfully decoded.*/
+ − l1s.repeated_sacch.srr = 1;
+ −
+ − }
+ − else
+ − {
+ − l1s.repeated_sacch.srr = 0; // debug
+ −
+ − }
+ −
+ −
+ − #endif /* (FF_REPEATED_SACCH == 1) */
+ − #if ((TESTMODE) && ((FF_REPEATED_SACCH == 1)) )
+ − } /* end else l1_config.repeat_sacch_enable */
+ − #endif /* ((TESTMODE) && ((FF_REPEATED_SACCH == 1))) */
+ −
+ − #if ((TRACE_TYPE==1 || TRACE_TYPE == 4) && (FF_REPEATED_SACCH))
+ − trace_info.repeat_sacch.srr = l1s.repeated_sacch.srr;
+ − if(b_joint == TRUE && b_fire1!=1)
+ − {
+ − trace_info.repeat_sacch.dl_combined_good_count ++;
+ − if (prevfail == 1)
+ − trace_info.repeat_sacch.dl_error_count--;
+ − }
+ − #endif /* ((TRACE_TYPE==1 || TRACE_TYPE == 4) && (FF_REPEATED_SACCH)) */
+ −
+ − #if ((TRACE_TYPE==1 || TRACE_TYPE == 4) && (FF_REPEATED_SACCH))
+ − trace_info.repeat_sacch.srr = l1s.repeated_sacch.srr;
+ − if( rx_fail_flag == TRUE) /* Information reception failed */
+ − {
+ − trace_info.repeat_sacch.dl_error_count ++;
+ − }
+ −
+ − #endif /* ((TRACE_TYPE==1 || TRACE_TYPE == 4) && (FF_REPEATED_SACCH)) */
+ −
+ − #if TESTMODE
+ − // Continunous mode: the SAACH data aren't valid. Therefore don't send to L1A.
+ − if ((!l1_config.TestMode) || ((l1_config.TestMode) &&
+ − (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS)))
+ − #endif
+ − {
+ − // Allocate result message.
+ − msg = os_alloc_sig(sizeof(T_PH_DATA_IND));
+ − DEBUGMSG(status,NU_ALLOC_ERR)
+ − msg->SignalCode = L1C_SACCH_INFO;
+ − ((T_PH_DATA_IND *)(msg->SigP))->l2_channel_type = L2_CHANNEL_SACCH;
+ −
+ − // Catch L1 Header if SACCH/DL data block successfully received.
+ − if(rx_fail_flag == FALSE)
+ − {
+ − UWORD8 supplied_txpwr = info_address[3] & 0x0000001f;
+ − UWORD8 supplied_ta = (info_address[3] & 0x00007f00) >> 8;
+ −
+ − #if (FF_REPEATED_SACCH == 1)
+ − //Set SRO parameter to transmit to the UL
+ − l1s.repeated_sacch.sro = (info_address[3] & 0x00000040) >> 6;
+ − /*
+ − 7 | 6 | 5 | 4 3 2 1 0
+ − Spare | SRO| FPC EPC | Ordered MS power level
+ − | Ordered timing advance
+ −
+ − */
+ − #endif /* (FF_REPEATED_SACCH == 1) */
+ − // Check max transmit power (min txpwr) according to powerclass.
+ − supplied_txpwr = l1a_clip_txpwr(supplied_txpwr,l1a_l1s_com.dedic_set.radio_freq);
+ −
+ − #if TESTMODE
+ − // Update txpwr and ta only during Normal Mode
+ − if (!l1_config.TestMode)
+ − #endif
+ − {
+ − l1a_l1s_com.dedic_set.aset->new_target_txpwr = supplied_txpwr;
+ −
+ − // Check if supplied TA is valid, if not keep previous value.
+ − if(supplied_ta < 64)
+ − l1a_l1s_com.dedic_set.aset->new_timing_advance = supplied_ta;
+ − }
+ − #if ((TRACE_TYPE==1 || TRACE_TYPE == 4) && (FF_REPEATED_SACCH))
+ − l1s_check_sacch_dl_block(info_address);
+ − trace_info.repeat_sacch.sro = l1s.repeated_sacch.sro;
+ − #endif /* ((TRACE_TYPE==1 || TRACE_TYPE == 4) && (FF_REPEATED_SACCH)) */
+ − } /* end if rx_fail_flag */
+ − else
+ − {
+ − #if ((TRACE_TYPE==1 || TRACE_TYPE == 4) && (FF_REPEATED_SACCH))
+ − trace_info.repeat_sacch.dl_buffer_empty = TRUE;
+ − #endif
+ − }
+ −
+ − // Get 23 bytes info. from DSP.
+ − for (j=0, i=0; i<11; i++)
+ − {
+ − word32 = info_address[3 + i]; // Get info word, rem: skip info. header.
+ − ((T_PH_DATA_IND *)(msg->SigP))->l2_frame.A[j++] = (word32 & 0x000000ff);
+ − ((T_PH_DATA_IND *)(msg->SigP))->l2_frame.A[j++] = (word32 & 0x0000ff00) >> 8;
+ − }
+ − ((T_PH_DATA_IND *)(msg->SigP))->l2_frame.A[22] = (info_address[14] & 0x000000ff);
+ −
+ − // Fill msg header...
+ − ((T_PH_DATA_IND *)(msg->SigP))->rf_chan_num = l1a_l1s_com.Scell_info.radio_freq;
+ − ((T_PH_DATA_IND *)(msg->SigP))->error_cause = rx_fail_flag;
+ − ((T_PH_DATA_IND *)(msg->SigP))->bsic = l1a_l1s_com.Scell_info.bsic;
+ − ((T_PH_DATA_IND *)(msg->SigP))->tc = l1s.actual_time.tc;
+ −
+ − // send message...
+ −
+ − os_send_sig(msg, L1C1_QUEUE);
+ − DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+ −
+ − #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+ − trace_info.sacch_d_nerr = info_address[2] & 0x00ff;
+ − #endif
+ − #if (FF_REPEATED_SACCH == 1)
+ − prevfail= rx_fail_flag ;
+ − #endif /* (FF_REPEATED_SACCH == 1) */
+ − }
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1s_read_dcch_dl() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : reads FACCH DL data block. */
+ − /*-------------------------------------------------------*/
+ − void l1s_read_dcch_dl(API *info_address, UWORD32 task_rx)
+ − {
+ − UWORD8 rx_valid_flag = FALSE;
+ − UWORD8 timing_advance = 255;
+ − BOOL b_joint ; /* DSP indicator to Chase Combining */
+ − #if (L1_SAGEM_INTERFACE == 1)
+ − UWORD8 channel_type = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type;
+ − #endif
+ −
+ − #if (FF_REPEATED_DL_FACCH == 1)
+ − b_joint = (BOOL) (((info_address[0] & 0xffff) & (1<<B_JOINT)) >> B_JOINT);
+ −
+ − #if TESTMODE
+ − if(l1_config.repeat_facch_dl_enable != REPEATED_FACCHDL_ENABLE) /* repeated FACCH mode is disabled */
+ − b_joint = FALSE;
+ − #endif /* TESTMODE */
+ −
+ − #endif /* (FF_REPEATED_DL_FACCH == 1) */
+ −
+ −
+ − if(info_address != NULL)
+ − // A data block must be passed to L2.
+ − {
+ − UWORD32 b_fire1;
+ −
+ − #if (TRACE_TYPE!=0)
+ − if(task_rx == DDL) trace_fct(CST_L1S_READ_DCCH_DL__DDL, l1a_l1s_com.dedic_set.radio_freq_dd);
+ − if(task_rx == TCHTF) trace_fct(CST_L1S_READ_DCCH_DL__TCHTF, l1a_l1s_com.dedic_set.radio_freq_dd);
+ − if(task_rx == TCHTH) trace_fct(CST_L1S_READ_DCCH_DL__TCHTH, l1a_l1s_com.dedic_set.radio_freq_dd);
+ − #endif
+ −
+ − // Set detection flag.
+ − b_fire1 = ((info_address[0] & 0xffff) & (1<<B_FIRE1)) >> B_FIRE1;
+ − if(b_fire1 != 1)
+ − rx_valid_flag = TRUE; // information block received successfully.
+ − else
+ − rx_valid_flag = FALSE; // information block reception failled.
+ −
+ − if((rx_valid_flag == TRUE) && (l1a_l1s_com.dedic_set.aset->t3124 != 0))
+ − // T3124 running...
+ − // Check for PHYSICAL INFORMATION message from FACCH.
+ − {
+ − UWORD32 message_type = info_address[5] & 0x00ff;
+ −
+ − if(message_type == 0x2D)
+ − // FACCH message is a PHYSICAL INFORMATION message.
+ − {
+ − // Catch TIMING ADVANCE information.
+ − timing_advance = (UWORD8)((info_address[5] & 0xff00) >> 8);
+ − l1a_l1s_com.dedic_set.aset->new_timing_advance = timing_advance;
+ − l1a_l1s_com.dedic_set.aset->timing_advance = timing_advance;
+ −
+ − // Reset T3124.
+ − l1a_l1s_com.dedic_set.aset->t3124 = 0;
+ −
+ − // Stop sending Handover Access burst.
+ − l1a_l1s_com.dedic_set.aset->ho_acc_to_send = 0;
+ −
+ − // Handover access procedure is completed.
+ − // -> send L1C_HANDOVER_FINISHED message with "cause = COMPLETED" to L1A.
+ − l1s_send_ho_finished(HO_COMPLETE);
+ − }
+ − }
+ −
+ − // Clear 1st word of header.
+ − info_address[0] = 0;
+ −
+ − // Shift data block pointer to skip DSP header.
+ − info_address = &(info_address[3]);
+ −
+ − if (rx_valid_flag == TRUE)
+ − {
+ − #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+ − trace_info.facch_dl_count ++;
+ − #endif
+ − #if (FF_REPEATED_DL_FACCH == 1) /*Fire code is correct and information recieved successfully */
+ − l1s_store_facch_buffer(l1s.repeated_facch, info_address);
+ − #endif
+ −
+ − /* trace for FER calculation (Repeated FACCH mode): */
+ − /* nb of DL FACCH blocks correctly decoded which is not a repetition */
+ −
+ − #if ((TRACE_TYPE==1|| TRACE_TYPE==4) && (FF_REPEATED_DL_FACCH))
+ − trace_info.facch_dl_good_block_reported++;
+ − if(b_joint == TRUE) /* The combined block is successfully decoded */
+ − trace_info.facch_dl_combined_good_count++;
+ − #endif /* ((TRACE_TYPE==1|| TRACE_TYPE==4) && (FF_REPEATED_DL_FACCH)) */
+ − #if (DEBUG_DEDIC_TCH_BLOCK_STAT == 1)
+ − Trace_dedic_tch_block_stat(FACCH_GOOD, l1s_dsp_com.dsp_ndb_ptr->a_fd[2], 0);
+ − #endif
+ − }
+ − else
+ − {
+ − #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+ − trace_info.facch_dl_fail_count ++;
+ − #endif
+ − #if (DEBUG_DEDIC_TCH_BLOCK_STAT == 1)
+ − Trace_dedic_tch_block_stat(FACCH_BAD, l1s_dsp_com.dsp_ndb_ptr->a_fd[2], 0);
+ − #endif
+ − }
+ − }
+ − #if (FF_REPEATED_DL_FACCH == 1)
+ − if(rx_valid_flag == FALSE)
+ − {
+ − l1s.repeated_facch.pipeline[l1s.repeated_facch.counter_candidate].buffer_empty=TRUE;
+ − }
+ − #endif /* (FF_REPEATED_DL_FACCH == 1) */
+ −
+ − #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+ − RTTL1_FILL_DL_DCCH(rx_valid_flag, timing_advance)
+ − #endif
+ −
+ − // Pass data block to L2.
+ − #if (SEND_FN_TO_L2_IN_DCCH==1)
+ − #if (L1_SAGEM_INTERFACE == 1)
+ − dll_dcch_downlink(info_address, rx_valid_flag, l1s.actual_time.fn, channel_type);
+ − #else
+ − dll_dcch_downlink(info_address, rx_valid_flag, l1s.actual_time.fn);
+ − #endif
+ − #else
+ − #if (L1_SAGEM_INTERFACE == 1)
+ − dll_dcch_downlink(info_address, rx_valid_flag, channel_type);
+ − #else
+ − dll_dcch_downlink(info_address, rx_valid_flag);
+ − #endif
+ − #endif
+ −
+ − }
+ −
+ − #if (CHIPSET==15)
+ − /*-------------------------------------------------------*/
+ − /* l1s_reset_tx_ptr() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : Reset the TX data pointer for DRP */
+ − /* after ABORT */
+ − /*-------------------------------------------------------*/
+ −
+ − #define L1_DRP_TX_PTR_RESET_SET (0x00000020)
+ − #define L1_DRP_TX_PTR_RESET_RESET (~(L1_DRP_TX_PTR_RESET_SET))
+ −
+ − void l1s_reset_tx_ptr(UWORD8 param1, UWORD8 param2)
+ − {
+ − volatile UWORD32 *ptr_drp_init32;
+ − ptr_drp_init32 = (UWORD32 *) (DRP_API_BASE_ADDRESS + DRP_REG_SRM_CW_ADDR); //0xFFFF1E00;
+ −
+ − // Set the TX_PTR_RESET bit to 1 to reset TX RD and WR pointers
+ − (*ptr_drp_init32) = (*ptr_drp_init32)|(L1_DRP_TX_PTR_RESET_SET);
+ −
+ − // Reset the bit to zero as aslong as the bit is 1, pointers are in reset state
+ − (*ptr_drp_init32) = (*ptr_drp_init32)&(L1_DRP_TX_PTR_RESET_RESET);
+ − }
+ − #endif