FreeCalypso > hg > fc-tourmaline
view src/cs/layer1/tm_cfile/l1tm_async.c @ 273:5caa86ee2cfa
enable L1_NEW_AEC in l1_confg.h (bold change)
The AEC function implemented in DSP ROM 3606 on the Calypso silicon
we work with is the one that corresponds to L1_NEW_AEC; the same holds
for DSP 34 and even for DSP 33 with more recent patch versions.
However, TI shipped their TCS211 reference fw with L1_NEW_AEC set to 0,
thus driving AEC the old way if anyone tried to enable it, either via
AT%Nxxxx or via the audio mode facility. As a result, the fw would
try to control features which no longer exist in the DSP (long vs short
echo and the old echo suppression level bits), while providing no way
to tune the 8 new parameter words added to the DSP's NDB page.
The only sensible solution is to bite the bullet and enable L1_NEW_AEC
in L1 config, with fallout propagating into RiViera Audio Service
T_AUDIO_AEC_CFG structure and into /aud/*.cfg binary file format.
The latter fallout will be addressed in further code changes.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 29 Jul 2021 18:32:40 +0000 |
parents | 4e78acac3d88 |
children |
line wrap: on
line source
/************* Revision Controle System Header ************* * GSM Layer 1 software * L1TM_ASYNC.C * * Filename l1tm_async.c * Copyright 2003 (C) Texas Instruments * ************* Revision Controle System Header *************/ #include "l1_macro.h" #include "l1_confg.h" #if TESTMODE #define L1TM_ASYNC_C #include <string.h> #include <stdlib.h> #include "l1_types.h" #include "sys_types.h" #include "l1_const.h" #include "l1_time.h" #include "l1_signa.h" #include "cust_os.h" #include "l1tm_defty.h" #if (AUDIO_TASK == 1) #include "l1audio_const.h" #include "l1audio_cust.h" #include "l1audio_defty.h" #include "l1audio_signa.h" #include "l1audio_proto.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 #include "l1_defty.h" #include "l1_msgty.h" #include "l1_varex.h" #include "l1_proto.h" #include "l1tm_msgty.h" #include "l1tm_signa.h" #include "l1tm_varex.h" #if (L1_STEREOPATH == 1) #include "sys_dma.h" #include "l1audio_stereo.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 /* FreeCalypso TCS211 reconstruction */ #define ETM_PROTOCOL 0 #define ETM_MODE 0 //------------------------------------ // Prototypes from external functions //------------------------------------ #if (OP_L1_STANDALONE == 1) void etm_core(xSignalHeaderRec *msg); #endif void Cust_tm_init(void); void l1tm_stats_fb_confirm (T_TMODE_FB_CON *prim, WORD32 test); void l1tm_stats_sb_confirm (T_TMODE_NCELL_SYNC_IND *prim, WORD32 test); void l1tm_stats_bcch_confirm (T_TMODE_BCCHS_CON *prim); void l1tm_stats_tch_confirm (T_TMODE_TCH_INFO *prim); void l1tm_stats_mon_confirm (T_TMODE_FB_CON *prim); void l1tm_stats_full_list_meas_confirm(T_TMODE_RXLEV_REQ *prim); BOOL l1tm_is_rx_counter_done (void); void l1tm_reset_rx_state (void); void l1tm_rf_param_write (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_rf_param_read (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_rf_table_write (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_rf_table_read (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_rx_param_write (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_rx_param_read (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_tx_param_write (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_tx_param_read (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_tx_template_write (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_tx_template_read (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_special_param_write (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_special_param_read (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_special_table_write (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_special_table_read (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_special_enable (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_rf_enable (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_stats_config_write (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_stats_config_read (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_statistics (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_stats_read (T_TM_RETURN *tm_return, WORD16 type, UWORD16 bitmask); #if (L1_DRP == 1) void l1tm_drp_sw_write(T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); #endif void l1a_tmode_send_ul_msg (T_TM_RETURN *tm_ret); UWORD16 l1tm_convert_arfcn2l1ch(UWORD16 arfcn, UWORD8 *error_flag); void l1tm_fill_burst (UWORD16 pattern, UWORD16 *TM_ul_data); void l1tm_initialize_var (void); UWORD16 Convert_l1_radio_freq (SYS_UWORD16 radio_freq); void tm_transmit(T_TM_RETURN *tm_ret); #if (CODE_VERSION != SIMULATION) void l1tm_tpu_table_write (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); void l1tm_tpu_table_read (T_TESTMODE_PRIM *prim, T_TM_RETURN *tm_return); #endif #if L1_GPRS T_TRANSFER_SET *l1pa_get_free_transfer_set (UWORD8 new_tbf); T_CRES_LIST_PARAM *l1pa_get_free_cres_list_set(void); void l1tm_stats_pdtch_confirm (T_TMODE_PDTCH_INFO *prim); #endif #if (L1_TPU_DEV == 1) void l1tm_flexi_tpu_table_read(T_TESTMODE_PRIM * prim, T_TM_RETURN * tm_return); void l1tm_flexi_tpu_table_write(T_TESTMODE_PRIM * prim, T_TM_RETURN * tm_return); //Flexi ABB Delay void l1tm_flexi_abb_read(T_TESTMODE_PRIM * prim, T_TM_RETURN * tm_return); void l1tm_flexi_abb_write(T_TESTMODE_PRIM * prim, T_TM_RETURN * tm_return); #endif // DRP Calibration void l1tm_drp_calib_read(T_TESTMODE_PRIM * prim, T_TM_RETURN * tm_return); void l1tm_drp_calib_write(T_TESTMODE_PRIM * prim, T_TM_RETURN * tm_return); // Prototypes from internal functions //------------------------------------ void l1a_tmode_fb0_process(xSignalHeaderRec *msg); void l1a_tmode_fb1_process(xSignalHeaderRec *msg); void l1a_tmode_sb_process(xSignalHeaderRec *msg); void l1a_tmode_bcch_reading_process(xSignalHeaderRec *msg); void l1a_tmode_dedicated_process(xSignalHeaderRec *msg); void l1a_tmode_access_process(xSignalHeaderRec *msg); void l1a_tmode_full_list_meas_process(xSignalHeaderRec *msg); #if L1_GPRS void l1a_tmode_transfer_process(xSignalHeaderRec *msg); #endif #if ((L1_STEREOPATH == 1) && (OP_L1_STANDALONE == 1)) void l1a_tmode_audio_stereopath_process(xSignalHeaderRec *msg); extern void l1tm_stereopath_DMA_handler(SYS_UWORD16 dma_status); extern void l1tm_stereopath_fill_buffer(void* buffer_address); extern UWORD16 l1tm_stereopath_get_pattern(UWORD16 sampling_freq, UWORD16 sin_freq_left,UWORD16 sin_freq_right, UWORD8 data_type); extern void l1a_audio_send_confirmation(UWORD32 SignalCode); extern void l1_trigger_api_interrupt(void); #if ( ANLG_FAM == 11) //Add the two new sampling frequencies in the test mode for Locosto - 12khz and 24 khz const UWORD16 l1tm_stereopath_sampling_freqs[9] = {8000,11025,12000,16000,22050,24000,32000,44100,48000}; #else const UWORD16 l1tm_stereopath_sampling_freqs[8] = {48000,0,44100,32000,22050,16000,11025,8000}; #endif const UWORD16 l1tm_stereopath_sin_freqs[4][2] = {{0,0}, {100,1000}, {1000,10000}, {1000,1000}}; // 4 different pattern of two freqs const UWORD16 l1tm_stereopath_buffer[(480+1)*2]; T_STP_DRV_MCU_DSP *stp_drv_ndb = (T_STP_DRV_MCU_DSP *)API_address_dsp2mcu(C_STP_DRV_API_BASE_ADDRESS); #if (CODE_VERSION == NOT_SIMULATION) #pragma DATA_SECTION(TM_stereo_buf,".TM_stereo_buf"); #endif #if (CHIPSET == 15) #pragma DATA_SECTION(TM_stereo_buf_ext_mem, ".TM_stereo_buf_ext_mem"); #endif volatile WORD16 TM_stereo_buf[STEREOPATH_MAX_NB_OF_FRAMES*2]; #if (CHIPSET == 15) volatile WORD16 TM_stereo_buf_ext_mem[STEREOPATH_MAX_NB_OF_FRAMES*2]; #endif #endif // ((L1_STEREOPATH == 1) && (OP_L1_STANDALONE == 1)) /***********************************************************************/ /* TESTMODE 3.X */ /***********************************************************************/ // omaps00090550 static UWORD8 tx_param_band=0; // used in tx_param_write/read; default is GSM900 /*-----------------------------------------------------------*/ /* l1a_tmode() */ /*-----------------------------------------------------------*/ /* Description : State machine controls TestMode processes */ /* */ /* Starting messages: TMODE_BCCH_REQ */ /* TMODE_PM_REQ */ /* TMODE_FB0_REQ */ /* TMODE_FB1_REQ */ /* TMODE_SB_REQ */ /* */ /* */ /* Result messages (input): L1_TMODE_MEAS_REPORT */ /* L1_SB_INFO */ /* L1_BCCHS_INFO */ /* */ /* Result messages (output): TMODE_PM_CON */ /* MPH5_NCELL_SB_IND */ /* */ /* Reset messages (input): MPH5_STOP_BCCH_READING */ /* */ /*-----------------------------------------------------------*/ void l1a_tmode(xSignalHeaderRec *msg) { T_TESTMODE_PRIM *prim; T_TM_RETURN tm_ret; int SignalCode = msg->SignalCode; #if (OP_WCP==1) && (OP_L1_STANDALONE!=1) // Security check for Operating System platforms (open platforms) // We forbid TESTMODE if the phone is running with an OS // so users can not invoke TESTMODE for malicious goals extern unsigned long GC_RunningWithOs(); if(GC_RunningWithOs()) return; #endif if (SignalCode == TESTMODE_PRIM) { // use CID to decide what to do prim = (T_TESTMODE_PRIM *)(msg->SigP); // fill in the cid also named fid in the ETM protocol tm_ret.cid = prim->cid; switch (prim->cid) { case TM_INIT: l1tm_initialize(&tm_ret); break; case TM_MODE_SET: l1tm_mode_set(prim, &tm_ret); break; case VERSION_GET: l1tm_version_get(prim, &tm_ret); break; case RF_ENABLE: l1tm_rf_enable(prim, &tm_ret); break; case STATS_READ: l1tm_statistics(prim, &tm_ret); break; case STATS_CONFIG_WRITE: l1tm_stats_config_write(prim, &tm_ret); break; case STATS_CONFIG_READ: l1tm_stats_config_read(prim, &tm_ret); break; case RF_PARAM_WRITE: l1tm_rf_param_write(prim, &tm_ret); break; case RF_PARAM_READ: l1tm_rf_param_read(prim, &tm_ret); break; case RF_TABLE_WRITE: l1tm_rf_table_write(prim, &tm_ret); break; case RF_TABLE_READ: l1tm_rf_table_read(prim, &tm_ret); break; case RX_PARAM_WRITE: l1tm_rx_param_write(prim, &tm_ret); break; case RX_PARAM_READ: l1tm_rx_param_read(prim, &tm_ret); break; case TX_PARAM_WRITE: l1tm_tx_param_write(prim, &tm_ret); break; case TX_PARAM_READ: l1tm_tx_param_read(prim, &tm_ret); break; case TX_TEMPLATE_WRITE: l1tm_tx_template_write(prim, &tm_ret); break; case TX_TEMPLATE_READ: l1tm_tx_template_read(prim, &tm_ret); break; case MEM_WRITE: l1tm_mem_write(prim, &tm_ret); break; case MEM_READ: l1tm_mem_read(prim, &tm_ret); break; case CODEC_WRITE: l1tm_codec_write(prim, &tm_ret); break; case CODEC_READ: l1tm_codec_read(prim, &tm_ret); break; case MISC_PARAM_WRITE: l1tm_misc_param_write(prim, &tm_ret); break; case MISC_PARAM_READ: l1tm_misc_param_read(prim, &tm_ret); break; case MISC_ENABLE: l1tm_misc_enable(prim, &tm_ret); break; case SPECIAL_PARAM_WRITE: l1tm_special_param_write(prim, &tm_ret); break; case SPECIAL_PARAM_READ: l1tm_special_param_read(prim, &tm_ret); break; case SPECIAL_TABLE_WRITE: l1tm_special_table_write(prim, &tm_ret); break; case SPECIAL_TABLE_READ: l1tm_special_table_read(prim, &tm_ret); break; case SPECIAL_ENABLE: l1tm_special_enable(prim, &tm_ret); break; #if (L1_DRP == 1) case DRP_SW_WRITE: l1tm_drp_sw_write(prim, &tm_ret); break; #endif #if (CODE_VERSION != SIMULATION) case TPU_TABLE_WRITE: l1tm_tpu_table_write(prim, &tm_ret); break; case TPU_TABLE_READ: l1tm_tpu_table_read(prim, &tm_ret); break; #endif case TM_FFS: l1tm_ffs(prim, &tm_ret); break; #if(L1_TPU_DEV == 1) case FLEXI_TPU_TABLE_WRITE: l1tm_flexi_tpu_table_write(prim, &tm_ret); break; case FLEXI_TPU_TABLE_READ: l1tm_flexi_tpu_table_read(prim, &tm_ret); break; case FLEXI_ABB_WRITE: l1tm_flexi_abb_write(prim, &tm_ret); break; case FLEXI_ABB_READ: l1tm_flexi_abb_read(prim, &tm_ret); break; #endif #if 0 //(CODE_VERSION != SIMULATION) // FreeCalypso TCS211 reconstruction case DRP_CALIB_WRITE: l1tm_drp_calib_write(prim, &tm_ret); break; case DRP_CALIB_READ: l1tm_drp_calib_read(prim, &tm_ret); break; // TBD for Future Use #endif // CODE_VERSION default: #if (OP_L1_STANDALONE == 1) etm_core(msg); return; #else tm_ret.size = 0; #if (ETM_PROTOCOL == 1) tm_ret.status = -ETM_BADOP; #else tm_ret.status = E_BADCID; #endif #endif // OP_L1_STANDALONE break; } // end of switch tm_transmit(&tm_ret); } //end of TESTMODE_PRIM #if L1_GPRS else if ( ((SignalCode <= TMODE_PDTCH_INFO) && (SignalCode >= TMODE_RXLEV_REQ)) || (l1tm.tm_msg_received == TRUE) ) #else else if ( ((SignalCode <= TMODE_TCH_INFO) && (SignalCode >= TMODE_RXLEV_REQ)) || (l1tm.tm_msg_received == TRUE) ) #endif { #if (CODE_VERSION == SIMULATION) static BOOL tm_init = FALSE; if (! tm_init) { Cust_tm_init(); l1tm_initialize_var(); l1_config.TestMode = 1; tm_init=TRUE; } #endif l1a_tmode_fb0_process(msg); l1a_tmode_fb1_process(msg); l1a_tmode_sb_process(msg); l1a_tmode_bcch_reading_process(msg); l1a_tmode_dedicated_process(msg); l1a_tmode_access_process(msg); l1a_tmode_full_list_meas_process(msg); #if L1_GPRS l1a_tmode_transfer_process(msg); #endif #if ((L1_STEREOPATH == 1) && (OP_L1_STANDALONE == 1)) l1a_tmode_audio_stereopath_process(msg); #endif } //end of not TESTMODE_PRIM } // end of procedure. /*-------------------------------------------------------*/ /* l1a_tmode_fb0_process() */ /*-------------------------------------------------------*/ /* Description : This state machine handles the 1st */ /* synchronization with the network in Test Mode. */ /* */ /* Starting messages: TMODE_FB0_REQ */ /* */ /* Result messages (input): L1C_FB_INFO */ /* */ /*-------------------------------------------------------*/ void l1a_tmode_fb0_process(xSignalHeaderRec *msg) { enum states { RESET = 0, // Reset state. WAIT_INIT = 1, // Initial state. SET_FS_FB_MODE0 = 2, // First Synchro, Setting of 1st FB mode 0. WAIT_FS_FB_MODE0 = 3 // First Synchro, 1st FB mode 0 state. }; UWORD8 *state = &l1a.state[TMODE_FB0]; UWORD32 SignalCode = msg->SignalCode; BOOL done = 0; #if (VCXO_ALGO == 1) #define FS_FB_MODE0_CENTER 1 #define FS_FB_MODE0_MAX 2 #define FS_FB_MODE0_MIN 3 static WORD16 state_vcxo; static WORD16 static_attempt_counter; #endif BOOL end_process = 0; while(!end_process) { switch(*state) { case RESET: { // Step in state machine. *state = WAIT_INIT; #if (VCXO_ALGO == 1) if(l1_config.params.eeprom_afc == 0) { // Go to the initial VCXO AFC_INIT algorithm state state_vcxo = FS_FB_MODE0_CENTER; static_attempt_counter = 0; } #endif // Reset tasks used in the process. l1a_l1s_com.l1s_en_task[FBNEW] = TASK_DISABLED; // in tmode, not ALR l1a_l1s_com.l1s_en_task[NSYNC] = TASK_DISABLED; // Disable neighbour sync 0. l1a_l1s_com.nsync.list[0].status = NSYNC_FREE; } break; case WAIT_INIT: { if (SignalCode == TMODE_FB0_REQ) { #if (CODE_VERSION == SIMULATION) l1tm_reset_rx_state(); #endif // Flag msg received l1tm.tm_msg_received = TRUE; // Set task semaphores. l1a_l1s_com.task_param[FBNEW] = SEMAPHORE_SET; // Set "parameter synchro semaphore for FB task. l1a_l1s_com.task_param[NSYNC] = SEMAPHORE_SET; // Set "parameter synchro semaphore for FB task. l1a_l1s_com.nsync.current_list_size = 0; // Downlink stuff timeslot is 0 (default in CS) l1a_l1s_com.dl_tn = 0; // Set arfcn l1a_l1s_com.nsync.list[0].radio_freq =l1_config.tmode.rf_params.bcch_arfcn; //Set timing validity for FB no a priori info l1a_l1s_com.nsync.list[0].timing_validity = 0; // Reset offset and time alignment l1a_l1s_com.nsync.list[0].fn_offset = 0; l1a_l1s_com.nsync.list[0].time_alignmt = 0; // Set functional mode. l1a_l1s_com.mode = CS_MODE; //Needs to be set for l1ddsp_load_monit_task() // Wideband search for FB detection. l1a_l1s_com.fb_mode = FB_MODE_0; // Enable SYNCHRO task to cleanup the MFTAB. l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED; // Initialize AFC control function. #if AFC_ALGO if (l1_config.afc_enable) { // l1_config.TestMode MUST == 1 #if (VCXO_ALGO == 1) // The TM rfpw 10 parameter has a different meaning when using // a VCXO. Instead of containing the AFC used for the FB0, which // is stored in the rftw 9 table now, it tells the TM which "state" must // be used for the VCXO algorithm // switch(l1_config.params.eeprom_afc) { case 0: // Full VCXO algo // The AFC_INIT state is controlled by the state machine // Reset attempt counter static_attempt_counter = 0; state_vcxo = FS_FB_MODE0_CENTER; break; case FS_FB_MODE0_CENTER * 8: state_vcxo = FS_FB_MODE0_CENTER; break; case FS_FB_MODE0_MIN * 8: state_vcxo = FS_FB_MODE0_MIN; break; case FS_FB_MODE0_MAX * 8: state_vcxo = FS_FB_MODE0_MAX; break; default: state_vcxo = FS_FB_MODE0_CENTER; } #endif } #endif // Step in state machine *state = SET_FS_FB_MODE0; } else { // End of process. return; } } break; case SET_FS_FB_MODE0: { // Step in state machine. *state = WAIT_FS_FB_MODE0; // Enable neighbour sync 0. l1a_l1s_com.nsync.list[0].status = NSYNC_PENDING; //Used by l1s_schedule_tasks in l1_sync // Enable NSYNC task for FB detection mode 0. l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED; if (l1_config.afc_enable) {// l1_config.TestMode MUST == 1 #if (VCXO_ALGO == 1) switch(state_vcxo) { case FS_FB_MODE0_CENTER: l1s.afc = l1ctl_afc(AFC_INIT_CENTER, &l1s.afc_frame_count, NULL, 0, l1a_l1s_com.nsync.list[0].radio_freq,l1a_l1s_com.mode); break; case FS_FB_MODE0_MIN: l1s.afc = l1ctl_afc(AFC_INIT_MIN, &l1s.afc_frame_count, NULL, 0, l1a_l1s_com.nsync.list[0].radio_freq,l1a_l1s_com.mode); break; case FS_FB_MODE0_MAX: l1s.afc = l1ctl_afc(AFC_INIT_MAX, &l1s.afc_frame_count, NULL, 0, l1a_l1s_com.nsync.list[0].radio_freq,l1a_l1s_com.mode); break; default: l1s.afc = l1ctl_afc(AFC_INIT_CENTER, &l1s.afc_frame_count, NULL, 0, l1a_l1s_com.nsync.list[0].radio_freq,l1a_l1s_com.mode); } #else l1s.afc = l1ctl_afc(AFC_INIT, &l1s.afc_frame_count, l1_config.params.eeprom_afc, 0, l1a_l1s_com.nsync.list[0].radio_freq); #endif } // (l1_config.afc_enable) is TRUE // End of process. end_process = 1; } break; case WAIT_FS_FB_MODE0: { if(SignalCode == L1C_FB_INFO) // Frequency Burst acquisition result. //------------------------------------ { BOOL fb_found = ((T_L1C_FB_INFO *) (msg->SigP))->fb_flag; if (fb_found) { // We consider the result of this successfull FB search attempt // as a good a-priori information for next attempt. // "fn_offset" is reversed to satisfy its definition, // fn_offset = Fn_neigh - Fn_serving. l1a_l1s_com.nsync.list[0].timing_validity = 1; l1a_l1s_com.nsync.list[0].fn_offset = 51 - l1a_l1s_com.nsync.list[0].fn_offset; } #if (VCXO_ALGO == 1) else { if(l1_config.params.eeprom_afc == 0) { //- Full VCXO algo // Increment "static_attempt_counter". static_attempt_counter++; if(static_attempt_counter < 4) { // Max number of attemps not reached yet... // try again with the same VCXO state *state = SET_FS_FB_MODE0; // Do not accumulate the statistics yet, just try again break; } else { // Max number of attempt is reached... go back to 1st FB mode 0. // Step in state machine. static_attempt_counter = 0; // Go to the next FS_FB_MODE0_CENTER state (CENTER -> MAX -> MIN) // After MIN go to CENTER again, which means that the attempt failed switch(state_vcxo) { case FS_FB_MODE0_CENTER: state_vcxo = FS_FB_MODE0_MAX; break; case FS_FB_MODE0_MAX: state_vcxo = FS_FB_MODE0_MIN; break; default: // i.e. case FS_FB_MODE0_MAX: // The algorithm tried all the AFC_INIT values (CENTER, MAX & MIN) // but did not detect an FB in any of the attemps for these values: // The current attempt FAILED => Continue and accumulate the statistics state_vcxo = FS_FB_MODE0_CENTER; break; } if (state_vcxo != FS_FB_MODE0_CENTER) { *state = SET_FS_FB_MODE0; // Do not accumulate the statistics yet, just try again with the new // selected state_vcxo break; // This breaks from the switch(*state), and thus re-loops thanks to the while(!end_process) } // (state_vcxo != FS_FB_MODE0_CENTER) } // (static_attempt_counter >= 4) } // (l1_config.params.eeprom_afc != 0) } // (fb_found) is FALSE #endif #if (VCXO_ALGO == 1) if(l1_config.params.eeprom_afc == 0) { // If we got this far, the attempt ended (with a fail or a success) // So we can go back to the initial state state_vcxo = FS_FB_MODE0_CENTER; } #endif //accumulate FB stats l1tm_stats_fb_confirm( (T_TMODE_FB_CON*) ((T_L1C_FB_INFO *) (msg->SigP)), 0); done = l1tm_is_rx_counter_done(); if (done == 1) { // Loop counter expired, stop the test *state = RESET; // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; break; // break out of switch } *state = SET_FS_FB_MODE0; } else if (SignalCode == TMODE_STOP_RX_TX) // Stop SYNC mode message. //-------------------------------- { // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; // Step in state machine. *state = RESET; return; } else { // End of process. return; } } break; } } } /*-------------------------------------------------------*/ /* l1a_tmode_fb1_process() */ /*-------------------------------------------------------*/ /* Description : This state machine handles the 1st */ /* synchronization with the network in Test Mode. */ /* */ /* Starting messages: TMODE_FB1_REQ */ /* */ /* Result messages (input): L1C_FB_INFO */ /* */ /*-------------------------------------------------------*/ void l1a_tmode_fb1_process(xSignalHeaderRec *msg) { enum states { RESET = 0, // Reset state. WAIT_INIT = 1, // Initial state. SET_FS_FB_MODE1 = 2, // First Synchro, Setting of 1st FB mode 1. WAIT_FS_FB_MODE1 = 3 // First Synchro, FB mode 1 state. }; UWORD8 *state = &l1a.state[TMODE_FB1]; UWORD32 SignalCode = msg->SignalCode; BOOL done = 0; BOOL end_process = 0; while(!end_process) { switch(*state) { case RESET: { // Step in state machine. *state = WAIT_INIT; // Reset of tasks used in this process is carried out in WAIT_FS_FBMODE1 state // Otherwise we would possibly reset the task set by l1a_tmode_fb0_process() } break; case WAIT_INIT: { if (SignalCode == TMODE_FB1_REQ) { #if (CODE_VERSION == SIMULATION) l1tm_reset_rx_state(); #endif // Flag msg received l1tm.tm_msg_received = TRUE; // Set task semaphores. l1a_l1s_com.task_param[FBNEW] = SEMAPHORE_SET; // Set "parameter synchro semaphore for FB task. l1a_l1s_com.task_param[NSYNC] = SEMAPHORE_SET; // Set "parameter synchro semaphore for FB task. // Downlink stuff timeslot is 0 (default in CS) l1a_l1s_com.dl_tn = 0; // Set arfcn l1a_l1s_com.nsync.list[0].radio_freq =l1_config.tmode.rf_params.bcch_arfcn; // Set functional mode. l1a_l1s_com.mode = CS_MODE; //Needs to be set for l1ddsp_load_monit_task() // Set FB detection mode. l1a_l1s_com.fb_mode = FB_MODE_1; // Step in state machine *state = SET_FS_FB_MODE1; } else { // End of process. return; } } break; case SET_FS_FB_MODE1: { // Step in state machine. *state = WAIT_FS_FB_MODE1; // Enable neighbour sync 0. l1a_l1s_com.nsync.list[0].status = NSYNC_PENDING; // Enable NSYNC task for FB detection mode 1. l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED; // End of process. end_process = 1; } break; case WAIT_FS_FB_MODE1: { // Use incoming message. //---------------------- if(SignalCode == L1C_FB_INFO) { //accumulate FB stats l1tm_stats_fb_confirm( (T_TMODE_FB_CON*) ((T_L1C_FB_INFO *) (msg->SigP)), 0); // increment counter done = l1tm_is_rx_counter_done(); if (done == 1) { // Loop counter expired, stop the test *state = RESET; // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; // Reset tasks used in the process. l1a_l1s_com.l1s_en_task[FBNEW] = TASK_DISABLED; // in tmode, not ALR l1a_l1s_com.l1s_en_task[NSYNC] = TASK_DISABLED; // Disable neighbour sync 0. l1a_l1s_com.nsync.list[0].status = NSYNC_FREE; break; // break out of switch } *state = SET_FS_FB_MODE1; } // end if L1C_FB_INFO else if (SignalCode == TMODE_STOP_RX_TX) // Stop SYNC mode message. //-------------------------------- { // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; // Step in state machine. *state = RESET; return; } else // No action in this machine for other messages. //---------------------------------------------- { // End of process. return; } } break; } } } /*-------------------------------------------------------*/ /* l1a_tmode_sb_process() */ /*-------------------------------------------------------*/ /* Description : This state machine handles the 1st */ /* synchronization with the network in Test Mode. */ /* */ /* Starting messages: TMODE_SB_REQ */ /* */ /* Result messages (input): L1C_SB_INFO */ /* */ /*-------------------------------------------------------*/ void l1a_tmode_sb_process(xSignalHeaderRec *msg) { enum states { RESET = 0, // Reset state. WAIT_INIT = 1, // Initial state. SET_FS_SB = 2, // Set SB WAIT_FS_SB = 3, // Wait for SB result NEW_SYNCHRO = 4 // Camp on cell }; UWORD8 *state = &l1a.state[TMODE_SB]; UWORD32 SignalCode = msg->SignalCode; BOOL done = 0; static UWORD8 static_bsic; static UWORD32 static_fn_offset; static UWORD32 static_time_alignmt; BOOL end_process = 0; while(!end_process) { switch(*state) { case RESET: { // Step in state machine. *state = WAIT_INIT; // Reset of tasks used in this process is carried out in WAIT_FS_SB state // Otherwise we would possibly reset the NSYNC task set by l1a_tmode_fb0_process() // or l1a_tmode_fb1_process } break; case WAIT_INIT: { if (SignalCode == TMODE_SB_REQ) { #if (CODE_VERSION == SIMULATION) l1tm_reset_rx_state(); #endif // Flag msg received l1tm.tm_msg_received = TRUE; // Set arfcn l1a_l1s_com.nsync.list[0].radio_freq =l1_config.tmode.rf_params.bcch_arfcn; // Enable NSYNC task for SB detection (SB2). #if ((REL99 == 1) && ((FF_BHO == 1) || (FF_RTD == 1))) l1a_l1s_com.nsync.list[0].timing_validity = SB_ACQUISITION_PHASE ; #else l1a_l1s_com.nsync.list[0].timing_validity = 3; #endif // Step in state machine *state = SET_FS_SB; } else { // End of process. return; } } break; case SET_FS_SB: { // Step in state machine. *state = WAIT_FS_SB; // Enable neighbour sync 0. l1a_l1s_com.nsync.list[0].status = NSYNC_PENDING; // Enable NSYNC task for SB detection. l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED; // End of process. end_process = 1; } break; case WAIT_FS_SB: { // Use incoming message. //---------------------- if(SignalCode == L1C_SB_INFO) { UWORD8 sb_found = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->sb_flag; UWORD8 bsic = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->bsic; if(sb_found == TRUE) // SB detection is a success... //----------------------------- { // Save Results. static_bsic = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->bsic; static_fn_offset = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->fn_offset; static_time_alignmt = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->time_alignmt; } l1tm_stats_sb_confirm( (T_TMODE_NCELL_SYNC_IND*) ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP)), 0); // if just an SB test, increment counter // if not done, just stay in this state, schedule a new attempt done = l1tm_is_rx_counter_done(); if (done == 1) { // step in state machine *state = NEW_SYNCHRO; // Reset NSYNC task and SB2 task enable flags. l1a_l1s_com.l1s_en_task[SB2] = TASK_DISABLED; // in tmode, not ALR l1a_l1s_com.l1s_en_task[NSYNC] = TASK_DISABLED; // Disable neighbour sync 0. l1a_l1s_com.nsync.list[0].status = NSYNC_FREE; // Save results. l1a_l1s_com.nsync.list[0].fn_offset = static_fn_offset; l1a_l1s_com.nsync.list[0].time_alignmt = static_time_alignmt; // Correct "ntdma" and "time_alignment" to shift 20 bit to the // future for Normal Burst reading tasks. l1a_add_time_for_nb(&l1a_l1s_com.nsync.list[0].time_alignmt, &l1a_l1s_com.nsync.list[0].fn_offset); break; // break out of switch } else // Make a new SB attempt { l1a_l1s_com.nsync.list[0].status = NSYNC_PENDING; // End of process. end_process = 1; } } else if (SignalCode == TMODE_STOP_RX_TX) // Stop SYNC mode message. //-------------------------------- { // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; // Step in state machine. *state = RESET; end_process = 1; } else // No action in this machine for other messages. //---------------------------------------------- { // End of process. end_process = 1; } }//End Case WAIT_FS_SB break; case NEW_SYNCHRO: { // Reset the Neighbor Cell information structure. l1a_reset_cell_info(&(l1a_l1s_com.Scell_info)); // STILL SAVING TSC WITHIN BSIC !!!!!!!!!!!!!!!! // Download ARFCN, timing information and bitmap from the command message. l1a_l1s_com.Scell_info.radio_freq = l1_config.tmode.rf_params.bcch_arfcn; l1a_l1s_com.Scell_info.bsic = static_bsic; l1a_l1s_com.Scell_info.time_alignmt = l1a_l1s_com.nsync.list[0].time_alignmt; l1a_l1s_com.Scell_info.fn_offset = l1a_l1s_com.nsync.list[0].fn_offset; // tn_difference -> loaded with the number of timeslot to shift. // dl_tn -> loaded with the new timeslot. l1a_l1s_com.tn_difference = 0 - l1a_l1s_com.dl_tn; l1a_l1s_com.dl_tn = 0; // Camping on timeslot 0. // Layer 1 internal mode is set to IDLE MODE. l1a_l1s_com.mode = I_MODE; // Set flag for toa init. #if (TOA_ALGO != 0) l1a_l1s_com.toa_reset = TRUE; #endif // Enable SYNCHRO tasks. l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED; // Step in state machine. *state = RESET; // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; } break; // break out of switch // omaps00090550 break; } } } /*-------------------------------------------------------*/ /* l1a_tmode_bcch_reading_process() */ /*-------------------------------------------------------*/ /* Description : This state machine handles serving cell */ /* BCCH reading in Test Mode. */ /* */ /* This process happens for a TestMode BCCH test, after */ /* completing FB's and SB's in */ /* l1a_tmode_initial_network_sync_process, */ /* and then passing through l1a_tmode_cres_process, */ /* */ /* OR */ /* */ /* it can also happen for a TestMode TCH with synch */ /* test where, FB's and SB's have already been detected, */ /* and 4 BCCH's will be received before moving to the */ /* TCH and dedicated mode. */ /* */ /* */ /* Starting messages: TMODE_SCELL_NBCCH_REQ */ /* ------------------ */ /* */ /* */ /* Result messages (input): L1C_BCCHS_INFO */ /* ------------------------ */ /* System information data block from L1S. */ /* */ /* */ /* Reset messages (input): TMODE_STOP_SCELL_BCCH_REQ */ /* ----------------------- */ /* */ /*-------------------------------------------------------*/ void l1a_tmode_bcch_reading_process(xSignalHeaderRec *msg) { enum states { RESET = 0, WAIT_INIT = 1, NBCCHS_CONFIG = 2, WAIT_BCCHS_RESULT = 3 }; UWORD8 *state = &l1a.state[TMODE_BCCH]; UWORD32 SignalCode = msg->SignalCode; BOOL done = 0; BOOL end_process = 0; while(!end_process) { switch(*state) { case RESET: { // Step in state machine. *state = WAIT_INIT; // Reset CS_MEAS process. l1a_l1s_com.l1s_en_task[NBCCHS] = TASK_DISABLED; // Clear NBCCHS task enable flag. //l1a_l1s_com.l1s_en_task[EBCCHS] = TASK_DISABLED; // Clear EBCCHS task enable flag. } break; case WAIT_INIT: { if(SignalCode == TMODE_SCELL_NBCCH_REQ) { #if (CODE_VERSION == SIMULATION) l1tm_reset_rx_state(); #endif // Flag msg received l1tm.tm_msg_received = TRUE; // Request to read Normal BCCH from serving cell. l1a_l1s_com.Scell_info.radio_freq = l1_config.tmode.rf_params.bcch_arfcn; // Step in state machine. *state = NBCCHS_CONFIG; } else // No action in this machine for other messages. //---------------------------------------------- { // End of process. return; } } break; case NBCCHS_CONFIG: { UWORD8 i; // Set semaphores for Normal Serving BCCH reading task. l1a_l1s_com.task_param[NBCCHS] = SEMAPHORE_SET; // Download message content. //-------------------------- l1a_l1s_com.nbcchs.schedule_array_size = 1; for(i=0;i<l1a_l1s_com.nbcchs.schedule_array_size;i++) { l1a_l1s_com.nbcchs.schedule_array[i].modulus = 1; l1a_l1s_com.nbcchs.schedule_array[i].relative_position = 0; } // Enable NBCCHS task. l1a_l1s_com.l1s_en_task[NBCCHS] = TASK_ENABLED; // Step in state machine. *state = WAIT_BCCHS_RESULT; // End of process. end_process = 1; } break; case WAIT_BCCHS_RESULT: { if(SignalCode == L1C_BCCHS_INFO) // Serving cell BCCH reading result. //---------------------------------- { // this function takes care of loops management l1tm_stats_bcch_confirm( (T_TMODE_BCCHS_CON*) ((T_MPHC_DATA_IND *)(msg->SigP)) ); done = l1tm_is_rx_counter_done(); if (done == 1) { // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; // This process must be reset. *state = RESET; break; } else { // End of process. end_process = 1; } } else if (SignalCode == TMODE_STOP_RX_TX) // Stop BCCH mode message. //-------------------------------- { // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; // Step in state machine. *state = RESET; end_process = 1; } else // No action in this machine for other messages. //---------------------------------------------- { // End of process. end_process = 1; } } break; } // end of "switch". } // end of "while" } // end of procedure. /*-------------------------------------------------------*/ /* l1a_tmode_dedicated_process() */ /*-------------------------------------------------------*/ /* Description : This state machine handles the dedicated*/ /* mode setup in Test Mode (L1A side). */ /* */ /* Starting messages: TMODE_IMMED_ASSIGN_REQ */ /* */ /* Subsequent messages: */ /* */ /* Result messages (input): L1C_DEDIC_DONE */ /* */ /* Result messages (output): */ /* */ /* Reset messages (input): TMODE_STOP_RX_TX */ /* */ /*-------------------------------------------------------*/ void l1a_tmode_dedicated_process(xSignalHeaderRec *msg) { enum states { RESET = 0, WAIT_INIT = 1, WAIT_MSG = 2 }; T_DEDIC_SET *free_set; UWORD8 *state = &l1a.state[TMODE_DEDICATED]; UWORD32 SignalCode = msg->SignalCode; BOOL end_process = 0; while(!end_process) { switch(*state) { case RESET: { // Step in state machine. *state = WAIT_INIT; l1a_l1s_com.l1s_en_task[FB26] = TASK_DISABLED; // Reset FB26 task enable flag. // Reset D_NMEAS process. l1a_l1s_com.l1s_en_meas &= D_BAMS_MEAS_MASK; // Reset D_BAMS Measurement enable flag. l1a.l1a_en_meas[D_NMEAS] &= D_BAMS_MEAS_MASK; // Reset L1S dedicated mode manager trigger. l1a_l1s_com.dedic_set.SignalCode = NULL; } break; case WAIT_INIT: { switch(SignalCode) // switch on input message. //------------------------------- { case TMODE_IMMED_ASSIGN_REQ: // Immediate assignement message. //------------------------------- { UWORD8 maio_bef_sti; #if(L1_FF_MULTIBAND == 1) UWORD8 operative_radio_freq; #endif // Flag msg received l1tm.tm_msg_received = TRUE; #if (CODE_VERSION == SIMULATION) l1_config.tmode.rf_params.down_up = ((T_TMODE_IMMED_ASSIGN_REQ*)(msg->SigP))->ul_dl; l1tm_reset_rx_state(); l1_config.tmode.stats_config.num_loops = 26; // 0 actually means infinite #endif // save this info for later if (l1_config.tmode.rf_params.down_up == (TMODE_DOWNLINK|TMODE_UPLINK) && l1_config.tmode.rf_params.mon_tasks == 1) { l1a_l1s_com.nsync.list[0].radio_freq = l1_config.tmode.rf_params.mon_arfcn; } // Get Ptr to the free dedicated parameter set. // All important fields are initialised. free_set = l1a_get_free_dedic_set(); // Save given dedicated channel parameters from MPHC_IMMED_ASSIGN_REQ msg. //======================================================================== free_set->chan1.desc.chan_sel.h = 0; // no hopping free_set->chan1.desc.chan_sel.rf_channel.single_rf.radio_freq = l1_config.tmode.rf_params.tch_arfcn; //DON'T: union with radio_freq //free_set->chan1.desc.chan_sel.rf_channel.hopping_rf.maio=0; //free_set->chan1.desc.chan_sel.rf_channel.hopping_rf.hsn=0; free_set->chan1.desc.channel_type = l1_config.tmode.rf_params.channel_type; free_set->chan1.desc.subchannel = l1_config.tmode.rf_params.subchannel; free_set->chan1.desc.timeslot_no = l1_config.tmode.rx_params.slot_num; free_set->chan1.desc.tsc = l1_config.tmode.tx_params.tsc; //Set the loopback mode // 0: No loopback, 1: Loop A ... 6: Loop F if(l1_config.tmode.tx_params.burst_data >= 5 && l1_config.tmode.tx_params.burst_data <= 10 && l1_config.tmode.rf_params.down_up == (TMODE_DOWNLINK | TMODE_UPLINK)) { free_set->chan1.tch_loop = l1_config.tmode.tx_params.burst_data - 4; // For loop back the channel mode needs to be set to TCH/FS free_set->chan1.mode = TCH_FS_MODE; } else { free_set->chan1.tch_loop = 0; // no loopback // Rem1: Mode is forced to Signalling Only. if (l1_config.tmode.rf_params.channel_type == TCH_F) free_set->chan1.mode = TCH_FS_MODE; else free_set->chan1.mode = SIG_ONLY_MODE; } /* ;-------------------------------------------------------------------------- ; channel_desc_1 : ; chan_sel : ( h=FALSE, arfcn=5a ) ; channel_type = 1 (TCHFS) ; subchannel = 0 ; timeslot_no = 0 ; tsc = 5 ; timing_advance = 0 ; frequency_list : ; rf_chan_cnt = 0000 ; rf_chan_no : (0000, 0000, ...(total of 64)... 0000) ; starting_time = ; start_time_present = FALSE ; start_time : ; n32 = ; n51 = ; n26 = ; frequency_list_bef_sti ; rf_chan_cnt = 0000 ; rf_chan_no : (0000, 0000, ...(total of 64)... 0000) ; maio_bef_sti = 0 ; dtx_allowed = FALSE ; bcch_allocation = 0 carriers (...) UNUSED ; ba_id = 0 UNUSED ; pwrc = 5 ;-------------------------------------------------------------------------- */ free_set->ma.freq_list.rf_chan_cnt = 0; free_set->ma.freq_list.rf_chan_no.A[0] = 0; free_set->ma.freq_list_bef_sti.rf_chan_cnt = 0; free_set->ma.freq_list_bef_sti.rf_chan_no.A[0] = 0; //DedicNew maio_bef_sti = 0; free_set->new_timing_advance = l1_config.tmode.tx_params.timing_advance; free_set->dtx_allowed = 0; // New Timing Advance value must be applied on 1st frame of dedic. channel. free_set->timing_advance = free_set->new_timing_advance; l1a_l1s_com.dedic_set.pwrc = l1_config.tmode.tx_params.txpwr; // l1a_l1s_com.dedic_set.pwrc = 5; // change from TM2! // TXPWR command was given in Idle, save it in dedicated mode structure. free_set->new_target_txpwr = l1s.applied_txpwr = l1_config.tmode.tx_params.txpwr; // Serving Cell stays the same. free_set->cell_desc = l1a_l1s_com.Scell_info; #if(L1_FF_MULTIBAND == 0) free_set->cell_desc.traffic_meas_beacon = l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset]; free_set->cell_desc.traffic_meas = l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.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(l1a_l1s_com.Scell_info.radio_freq); free_set->cell_desc.traffic_meas_beacon = l1a_l1s_com.last_input_level[operative_radio_freq]; free_set->cell_desc.traffic_meas = l1a_l1s_com.last_input_level[operative_radio_freq]; #endif // #if(L1_FF_MULTIBAND == 0) else // Decode the "starting time field", since staying on the same serving // the same STI fn is saved in both "neig_sti_fn" and "serv_sti_fn". free_set->neig_sti_fn = -1; //l1a_decode_starting_time(((T_MPHC_IMMED_ASSIGN_REQ *)(msg->SigP))->starting_time); free_set->serv_sti_fn = free_set->neig_sti_fn; // Check/Fill "before starting time" fields. //l1a_fill_bef_sti_param(free_set, ((T_MPHC_IMMED_ASSIGN_REQ *)(msg->SigP))->starting_time.start_time_present); //No hopping channel // Save the "timeslot difference" between new and old configuration // in "tn_difference". // tn_difference -> loaded with the number of timeslot to shift. // dl_tn -> loaded with the new timeslot. l1a_l1s_com.tn_difference = free_set->chan1.desc.timeslot_no - l1a_l1s_com.dl_tn; l1a_l1s_com.dl_tn = free_set->chan1.desc.timeslot_no; // Save new TN id. // Set "fset" pointer to the new parameter set. l1a_l1s_com.dedic_set.fset = free_set; // Give new msg code to L1S. //TestMode: use existing L1S primitive name l1a_l1s_com.dedic_set.SignalCode = MPHC_IMMED_ASSIGN_REQ; // step in state machine. *state = WAIT_MSG; } break; } // end of "switch(SignalCode)". // end of process. end_process = 1; } break; case WAIT_MSG: { switch(SignalCode) // switch on input message. //------------------------------- { case L1C_DEDIC_DONE: // Dedicated channel activated. //----------------------------- { // if MON tasks are enabled, set up FB26 and D_BAMS_MEAS tasks now as well if (l1_config.tmode.rf_params.down_up == (TMODE_DOWNLINK|TMODE_UPLINK) && l1_config.tmode.rf_params.mon_tasks == 1) { l1a_l1s_com.task_param[FB26] = SEMAPHORE_SET; l1a_l1s_com.l1s_en_task[FB26] = TASK_ENABLED; #if (L1_12NEIGH ==1) //Set timing validity for FB no a priori info l1a_l1s_com.nsync.list[0].timing_validity = 0; // Enable neighbour sync 0. l1a_l1s_com.nsync.list[0].status = NSYNC_PENDING; //Used by l1s_schedule_tasks in l1_sync l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED; #endif } if (l1_config.tmode.rx_params.pm_enable) { // Reset the BA list structure l1a_reset_ba_list(); // Next measurement report must indicate INVALID. //meas_valid = FALSE; l1a_l1s_com.ba_list.nbr_carrier = 1; // l1a_l1s_com.nsync.list[0].radio_freq was set to mon_arfcn above l1a_l1s_com.ba_list.A[0].radio_freq = l1a_l1s_com.nsync.list[0].radio_freq; // Set parameter synchro semaphore for D_BAMS task. // Enable Dedicated mode BA list measurement task. l1a_l1s_com.meas_param |= D_BAMS_MEAS; l1a.l1a_en_meas[D_NMEAS] |= D_BAMS_MEAS; } // keep track of dedicated mode state. l1tm.tmode_state.dedicated_active = 1; // End of process. end_process = 1; } break; case TMODE_TCH_INFO: // TCH result messages. //----------------------- { // Check if RX stats done in TCH if (l1_config.tmode.rf_params.mon_report == 0) { BOOL done; // loop and stats management done within this function l1tm_stats_tch_confirm((T_TMODE_TCH_INFO *) (msg->SigP)); done = l1tm_is_rx_counter_done(); if (done == 1) // if done, send stop message { l1tm.tmode_state.dedicated_active = 0; // Give new msg code to L1S. l1a_l1s_com.dedic_set.SignalCode = MPHC_STOP_DEDICATED_REQ; // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; #if (L1_12NEIGH ==1) l1a_l1s_com.l1s_en_task[NSYNC] = TASK_DISABLED; // Disable neighbour sync 0. l1a_l1s_com.nsync.list[0].status = NSYNC_FREE; //Used by l1s_schedule_tasks in l1_sync #endif // Step in state machine. *state = RESET; } } // end of process end_process = 1; } break; case L1C_FB_INFO: // MON result messages. //----------------------- { // Check if RX stats done in Monitor channel if (l1_config.tmode.rf_params.mon_report == 1) { BOOL done; // loop and stats management done within this function l1tm_stats_mon_confirm( (T_TMODE_FB_CON*) ((T_L1C_FB_INFO *) (msg->SigP))); done = l1tm_is_rx_counter_done(); if (done == 1) // if done, send stop message { l1tm.tmode_state.dedicated_active = 0; // Give new msg code to L1S. l1a_l1s_com.dedic_set.SignalCode = MPHC_STOP_DEDICATED_REQ; // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; #if (L1_12NEIGH ==1) l1a_l1s_com.l1s_en_task[NSYNC] = TASK_DISABLED; // Disable neighbour sync 0. l1a_l1s_com.nsync.list[0].status = NSYNC_FREE; //Used by l1s_schedule_tasks in l1_sync #endif // Step in state machine. *state = RESET; } } // end of process end_process = 1; } break; case TMODE_STOP_RX_TX: // Release dedicated mode message. //-------------------------------- { l1tm.tmode_state.dedicated_active = 0; // Give new msg code to L1S. l1a_l1s_com.dedic_set.SignalCode = MPHC_STOP_DEDICATED_REQ; // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; #if (L1_12NEIGH ==1) l1a_l1s_com.l1s_en_task[NSYNC] = TASK_DISABLED; // Disable neighbour sync 0. l1a_l1s_com.nsync.list[0].status = NSYNC_FREE; //Used by l1s_schedule_tasks in l1_sync #endif // Step in state machine. *state = RESET; end_process = 1; } break; default: // End of process. //---------------- { end_process = 1; } } // end of "switch(SignalCode)". } break; } // end of "switch". } // end of "while" } // end of procedure. /*-------------------------------------------------------*/ /* l1a_tmode_ra_process() */ /*-------------------------------------------------------*/ /* Description : This state machine handles the TestMode */ /* access to the network (IDLE mode). */ /* */ /* Starting messages: TMODE_RA_START */ /* */ /* Result messages (input): L1C_RA_DONE */ /* */ /* Result messages (output): TMODE_RA_DONE */ /* */ /* Stop messages (input): TMODE_STOP_RX_TX */ /* */ /*-------------------------------------------------------*/ void l1a_tmode_access_process(xSignalHeaderRec *msg) { enum states { RESET = 0, WAIT_INIT = 1, WAIT_RESULT = 2 }; UWORD8 *state = &l1a.state[TMODE_RA]; UWORD32 SignalCode = msg->SignalCode; BOOL done = 0; while(1) { switch(*state) { case RESET: { // Step in state machine. *state = WAIT_INIT; // Reset RAACC process. l1a_l1s_com.l1s_en_task[RAACC] = TASK_DISABLED; // Clear RAACC task enable flag. } break; case WAIT_INIT: { if(SignalCode == TMODE_RA_START) // Configuration message for Access Link. //--------------------------------------- { // Flag msg received l1tm.tm_msg_received = TRUE; l1s.applied_txpwr = l1_config.tmode.tx_params.txpwr; l1a_l1s_com.ra_info.channel_request = 2; //l1_config.tm_params.channel_request; // Initialize rand counter for RAACC process. l1a_l1s_com.ra_info.rand = 1; // rand is random number of frames to wait between each AB transmission. // In actual L1 code this changes with each burst. // It is set to 1 here so the test runs fast. // also, channel_request is constant in TestMode for all bursts. // Actual L1 changes channel_request message each time with a different // random reference. [channel_request = 3 bits for establishment cause // and 5 bits of random reference] // Use 2 multiframes (0.5 seconds) in reading all serving normal bursts // (like paging reorganization) to refine TOA since we must have the quarter // bit accuracy for RACH transmission. // Delay the start of RACH transmission (by incrementing rand // counter), only at the start of the test. if(l1a_l1s_com.bcch_combined) { l1a_l1s_com.ra_info.rand += 54; // Combined: 2 multiframes = 54 slots. } else { l1a_l1s_com.ra_info.rand += 102; // Not combined: 2 multiframes = 102 slots. } // step in state machine. *state = WAIT_RESULT; // TestMode does not set up full BCCH reading // Activate RAACC task (no semaphore for UL tasks). // TestMode does not enable Paging Reorg and Normal paging tasks. l1a_l1s_com.l1s_en_task[RAACC] = TASK_ENABLED; // Change mode to connection establishment part 1. l1a_l1s_com.mode = CON_EST_MODE1; // used for toa calc. } else // No action in this machine for other messages. //---------------------------------------------- { // End of process. return; } } break; case WAIT_RESULT: { if(SignalCode == L1C_RA_DONE) // Random access acknowledge message. //----------------------------------- { // Change mode to connection establishment part 2. l1a_l1s_com.mode = CON_EST_MODE2; // used for toa calc. //change power level and arfcn on the fly l1s.applied_txpwr = l1_config.tmode.tx_params.txpwr; // l1a_l1s_com.Scell_info.radio_freq = l1_config.tmode.rf_params.tch_arfcn; done = l1tm_is_rx_counter_done(); if (done) { // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; // No stats, just report end //tmstats_ra_confirm( (T_TMODE_RA_DONE*) ((T_MPHC_RA_CON *)(msg->SigP)) ); *state = RESET; } else // there are more loops to do... { l1a_l1s_com.ra_info.rand += 10; // 1 chosen/set for quicker test // Activate RAACC task (no semaphore for UL tasks). l1a_l1s_com.l1s_en_task[RAACC] = TASK_ENABLED; // end of process return; } } else if(SignalCode == TMODE_STOP_RX_TX) { // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; // No stats, just report end //tmstats_ra_confirm( (T_TMODE_RA_DONE*) ((T_MPHC_RA_CON *)(msg->SigP)) ); *state = RESET; return; } else // No action in this machine for other messages. //---------------------------------------------- { // End of process. return; } } break; } // end of "switch". } // end of "while" } // end of procedure. /*-------------------------------------------------------*/ /* l1a_tmode_full_list_meas_process() */ /*-------------------------------------------------------*/ /* */ /* Description: */ /* ------------ */ /* This function is a state machine which handles the */ /* Cell Selection Full List Power Measurement L1/L3 */ /* interface and it handles the neigbour cell */ /* measurement process in IDLE mode with FULL list. */ /* When a message MPHC_RXLEV_REQ is received */ /* the L1S task FSMS_MEAS is enabled. When this task */ /* is completed a reporting message L1C_VALID_MEAS_INFO */ /* is received and forwarded to L3. */ /* */ /* Starting messages: MPHC_RXLEV_REQ. */ /* */ /* Result messages (input): L1C_VALID_MEAS_INFO */ /* */ /* Result messages (output): MPHC_RXLEV_IND */ /* */ /* Reset messages (input): none */ /* */ /* Stop message (input): MPHC_STOP_RXLEV_REQ */ /* */ /* Stop message (output): MPHC_STOP_RXLEV_CON */ /* */ /* Rem: */ /* ---- */ /* L3 is in charge of the number of pass to follow the */ /* GSM recommendation. */ /* */ /*-------------------------------------------------------*/ void l1a_tmode_full_list_meas_process(xSignalHeaderRec *msg) { enum states { RESET = 0, WAIT_INIT = 1, WAIT_RESULT = 2 }; UWORD8 *state = &l1a.state[TMODE_FULL_MEAS]; UWORD32 SignalCode = msg->SignalCode; BOOL end_process = 0; while(!end_process) { switch(*state) { case RESET: { // Step in state machine. *state = WAIT_INIT; // Reset FULL_MEAS process. l1a_l1s_com.l1s_en_meas &= FSMS_MEAS_MASK; // Clear Cell Selection Measurement enable flag. } break; case WAIT_INIT: { if(SignalCode == TMODE_RXLEV_REQ) // Request to enter the Cell Selection measurements. //-------------------------------------------------- { UWORD16 i; // Flag msg received l1tm.tm_msg_received = TRUE; // Do NOT download info from message // In TestMode always a full scanning is done, therefore primitive does not send the list l1a_l1s_com.full_list_ptr=(T_FULL_LIST_MEAS *)((T_TMODE_RXLEV_REQ *)(msg->SigP)); // Single power measurement carried out on monitor channel l1a_l1s_com.full_list_ptr->power_array_size = 1; l1a_l1s_com.full_list_ptr->power_array[0].radio_freq = l1_config.tmode.rf_params.mon_arfcn; // Set "parameter synchro semaphores" l1a_l1s_com.meas_param |= FSMS_MEAS; // Reset the full list structure. l1a_reset_full_list(); // Reset the Input Level (IL) memory table. #if (L1_FF_MULTIBAND == 1) for(i=0; i<= NBMAX_CARRIER; i++) #else for(i=0; i<=l1_config.std.nbmax_carrier; i++) #endif { l1a_l1s_com.last_input_level[i].input_level = l1_config.params.il_min; l1a_l1s_com.last_input_level[i].lna_off = 0; } // Enable Cell Selection Full list measurement task. l1a.l1a_en_meas[TMODE_FULL_MEAS] |= FSMS_MEAS; // Step in state machine. *state = WAIT_RESULT; } // End of process. end_process = 1; } break; case WAIT_RESULT: { if(SignalCode == L1C_VALID_MEAS_INFO) // One valid measurement pass has been completed over the full list of carriers. //------------------------------------------------------------------------------ { BOOL done = FALSE; //-------------------------------------------------------- // WE COULD PUT HERE THE CODE TO TRANSLATE IL -> RXLEV !!! //-------------------------------------------------------- l1tm_stats_full_list_meas_confirm((T_TMODE_RXLEV_REQ *)(msg->SigP)); done = l1tm_is_rx_counter_done(); if (done) { // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; // Reset the machine. *state = RESET; } else { // Reset the full list structure. l1a_reset_full_list(); // Enable Cell Selection Full list measurement task. l1a.l1a_en_meas[TMODE_FULL_MEAS] |= FSMS_MEAS; // End of process end_process = 1; } } else if (SignalCode == TMODE_STOP_RX_TX) { // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; // Forward result message to L3. l1a_send_confirmation(TMODE_STOP_RXLEV_CON,RRM1_QUEUE); // Reset the machine. *state = RESET; end_process = 1; } else // No action in this machine for other messages. //---------------------------------------------- { // End of process. end_process = 1; } } break; } // end of "switch". } // end of "while" } // end of procedure. #if L1_GPRS /*-------------------------------------------------------*/ /* l1pa_tmode_transfer_process() */ /*-------------------------------------------------------*/ /* Description: */ /* ------------ */ /* */ /* Starting messages: */ /* ------------------ */ /* */ /* Subsequent messages: */ /* -------------------- */ /* */ /* Result messages (input): */ /* ------------------------ */ /* */ /* Result messages (output): */ /* ------------------------- */ /* */ /* Reset messages (input): */ /* ----------------------- */ /* */ /*-------------------------------------------------------*/ void l1a_tmode_transfer_process(xSignalHeaderRec *msg) { enum states { RESET = 0, WAIT_INIT = 1, WAIT_MSG = 2 }; UWORD8 *state = &l1a.state[TMODE_TRANSFER]; UWORD32 SignalCode = msg->SignalCode; static UWORD8 stat_gprs_slots; BOOL end_process = 0; while(!end_process) { switch(*state) { case RESET: { // Step in state machine. *state = WAIT_INIT; // Reset FB26 task enable flag. l1a_l1s_com.l1s_en_task[FB26] = TASK_DISABLED; // Reset TCR_MEAS process. l1pa_l1ps_com.l1ps_en_meas &= P_TCRMS_MEAS_MASK; // Disable Neighbour Measurement task. l1pa.l1pa_en_meas[TCR_MEAS] &= P_TCRMS_MEAS_MASK; // Reset Neighbour Measurement task. // Rise transfert parameter semaphore. l1pa_l1ps_com.transfer.semaphore = TRUE; } break; case WAIT_INIT: { switch(SignalCode) // switch on input message. //------------------------- { case TMODE_PDTCH_ASSIGN_REQ: // Assignement message. //--------------------- { static UWORD32 count =0; T_TRANSFER_SET *free_set; UWORD8 assignment_command; UWORD8 timeslot_alloc; UWORD8 timeslot; UWORD32 i; count++ ; #if (CODE_VERSION == SIMULATION) l1tm_reset_rx_state(); #endif // Flag msg received l1tm.tm_msg_received = TRUE; // Rise transfert parameter semaphore to prevent L1S to use partial configuration. l1pa_l1ps_com.transfer.semaphore = TRUE; assignment_command = BOTH_TBF; // Get Ptr to the free dedicated parameter set. // All important fields are initialised. free_set = l1pa_get_free_transfer_set(assignment_command); // Download message containt. free_set->assignment_id = 1; free_set->assignment_command = assignment_command; #if (CODE_VERSION == SIMULATION) free_set->multislot_class = ((T_TMODE_PDTCH_ASSIGN_REQ *)(msg->SigP))->multislot_class; #else free_set->multislot_class = l1_config.tmode.rf_params.multislot_class; #endif free_set->dl_pwr_ctl.p0 = 255; // no power control free_set->packet_ta.ta = 0; free_set->packet_ta.ta_index = 255; free_set->packet_ta.ta_tn = 255; free_set->tsc = l1_config.tmode.tx_params.tsc; free_set->freq_param.chan_sel.h = FALSE; // no hopping free_set->freq_param.chan_sel.rf_channel.single_rf.radio_freq = l1_config.tmode.rf_params.pdtch_arfcn; free_set->mac_mode = FIX_ALLOC_NO_HALF; // fixed allocation free_set->tbf_sti.present = TRUE; // STI present // FreeCalypso TCS211 reconstruction: LoCosto change backed out #if 0 //(CODE_VERSION == NOT_SIMULATION) // In order to reduce the latency for the ETM command "rfe 4", make absolute_fn as // next_time.fn+1. This was originally +100 because of which we had to wait for some // time before L1 actually starts the TBF. free_set->tbf_sti.absolute_fn= l1s.next_time.fn + 1; #else // In PC simulation, keep the old +100 to keep output logs same as reference free_set->tbf_sti.absolute_fn= l1s.next_time.fn + 100; // force to current FN+100 #endif free_set->interf_meas_enable = FALSE; // Interference measurements disabled free_set->pc_meas_chan = TRUE; // No measurement on the beacon (6 per MF52) // Allocation of both UL and DL time slots free_set->dl_tbf_alloc.tfi = 1; // DL TFI ID free_set->ul_tbf_alloc->tfi = 2; // UL TFI ID #if (CODE_VERSION == SIMULATION) free_set->dl_tbf_alloc.timeslot_alloc = ((T_TMODE_PDTCH_ASSIGN_REQ *)(msg->SigP))->dl_ts_alloc; free_set->ul_tbf_alloc->timeslot_alloc = ((T_TMODE_PDTCH_ASSIGN_REQ *)(msg->SigP))->ul_ts_alloc; l1_config.tmode.stats_config.num_loops = ((T_TMODE_PDTCH_ASSIGN_REQ *)(msg->SigP))->ul_alloc_length; l1_config.tmode.rf_params.mon_tasks = ((T_TMODE_PDTCH_ASSIGN_REQ *)(msg->SigP))->mon_enable; l1_config.tmode.rf_params.mon_report = ((T_TMODE_PDTCH_ASSIGN_REQ *)(msg->SigP))->mon_enable; l1_config.tmode.rx_params.pm_enable = ((T_TMODE_PDTCH_ASSIGN_REQ *)(msg->SigP))->pm_enable; #else free_set->dl_tbf_alloc.timeslot_alloc = l1_config.tmode.rx_params.timeslot_alloc; free_set->ul_tbf_alloc->timeslot_alloc = l1_config.tmode.tx_params.timeslot_alloc; #endif // free_set->ul_tbf_alloc->fixed_alloc.bitmap_length = l1_config.tmode.stats_config.num_loops; // force to 127 free_set->ul_tbf_alloc->fixed_alloc.bitmap_length = 127; // Init fixed allocation bitmap for (i=0;i<free_set->ul_tbf_alloc->fixed_alloc.bitmap_length;i++) free_set->ul_tbf_alloc->fixed_alloc.bitmap[i] = free_set->ul_tbf_alloc->timeslot_alloc; free_set->allocated_tbf = BOTH_TBF; // Process the downlink TBF first allocated timeslot timeslot_alloc = free_set->dl_tbf_alloc.timeslot_alloc; timeslot = 0; while((timeslot<7) && !(timeslot_alloc & (0x80>>timeslot))) { timeslot++; } free_set->dl_tbf_synchro_timeslot = timeslot; // Fill "synchro_timeslot" which will be the frame synchro slot. free_set->transfer_synchro_timeslot = timeslot; // save stats bitmap stat_gprs_slots = l1_config.tmode.stats_config.stat_gprs_slots; // Adjust stats bit map l1_config.tmode.stats_config.stat_gprs_slots <<= timeslot; // Process the uplink TBF first allocated timeslot // Fixed mode: the 1st allocated timeslot is the downlink control // timeslot allocated by the network, which is a timeslot allocated // in uplink timeslot_alloc = free_set->ul_tbf_alloc->timeslot_alloc; timeslot = 0; while((timeslot<7) && !(timeslot_alloc & (0x80>>timeslot))) { timeslot++; } // if UL synchro TS > DL synchro TS, then fixed alloc ctrl TS is the UL sync TS // else fixed alloc ctrl TS is the DL sync TS if (timeslot > free_set->dl_tbf_synchro_timeslot) free_set->ul_tbf_alloc->fixed_alloc.ctrl_timeslot = timeslot; else free_set->ul_tbf_alloc->fixed_alloc.ctrl_timeslot = free_set->dl_tbf_synchro_timeslot; free_set->ul_tbf_synchro_timeslot = free_set->ul_tbf_alloc->fixed_alloc.ctrl_timeslot; // Init txpwr levels for multi slot TX // txpwr[index] is calculated according to TX allocation given by MACS // timeslot contains the first allocated TS in UL for(i = timeslot; i < 8; i++) { l1pa_l1ps_com.transfer.dl_pwr_ctrl.txpwr[i] = l1_config.tmode.tx_params.txpwr_gprs[i]; } // Step in state machine. *state = WAIT_MSG; // Store signalcode. free_set->SignalCode = MPHP_ASSIGNMENT_REQ; // Clear transfer parameter semaphore to let L1S use the new parameters. l1pa_l1ps_com.transfer.semaphore = FALSE; // end of process. end_process = 1; } break; default: // End of process. //---------------- { return; } } // end switch(SignalCode) } // end case WAIT_INIT case WAIT_MSG: { switch(SignalCode) // switch on input message. //------------------------- { case L1P_TRANSFER_DONE: // Switch to TRANSFER mode has been done. { T_CRES_LIST_PARAM *free_list; // Set up TCR_MEAS task, if MON tasks are enabled set up FB26 if (l1_config.tmode.rf_params.mon_tasks == 1) { // Set FB26 task semaphore l1a_l1s_com.task_param[FB26] = SEMAPHORE_SET; // This process always use the first element of "nsync" structure. l1a_l1s_com.nsync.current_list_size = 0; // l1a_l1s_com.nsync.list[0].radio_freq was set to mon_arfcn above l1a_l1s_com.nsync.list[0].radio_freq = l1_config.tmode.rf_params.mon_arfcn; // Enable FB detection during packet transfer l1a_l1s_com.l1s_en_task[FB26] = TASK_ENABLED; #if (L1_12NEIGH ==1) //Set timing validity for FB no a priori info l1a_l1s_com.nsync.list[0].timing_validity = 0; // Enable neighbour sync 0. l1a_l1s_com.nsync.list[0].status = NSYNC_PENDING; //Used by l1s_schedule_tasks in l1_sync l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED; #endif } if (l1_config.tmode.rx_params.pm_enable) { // Set parameter synchro semaphore for P_TCRMS_MEAS task. l1pa_l1ps_com.meas_param |= P_TCRMS_MEAS; // Reset Neighbour Cell measurement parameters. l1pa_l1ps_com.tcr_freq_list.tcr_next_to_ctrl = 0; l1pa_l1ps_com.tcr_freq_list.tcr_next_to_read = 0; // Get Ptr to the free Neighbour meas list. // The number of carriers in the list and the list // identification are initialized. free_list = l1pa_get_free_cres_list_set(); // Download new list within T_CRES_LIST_PARAM structure. free_list->nb_carrier = 1; free_list->freq_list[0] = l1_config.tmode.rf_params.mon_arfcn; free_list->list_id = 0; // Set "flist" with Circuit Swithed BA frequency list parameters l1pa_l1ps_com.cres_freq_list.alist = free_list; // Reset flags. l1pa_l1ps_com.tcr_freq_list.ms_ctrl = 0; l1pa_l1ps_com.tcr_freq_list.ms_ctrl_d = 0; l1pa_l1ps_com.tcr_freq_list.ms_ctrl_dd = 0; // Reset measures made on beacon frequency. l1pa_l1ps_com.tcr_freq_list.beacon_meas = 0; // Enable Packet Transfer Neighbour Measurement task. l1pa.l1pa_en_meas[TCR_MEAS] |= P_TCRMS_MEAS; } // Flag packet transfer mode active l1tm.tmode_state.packet_transfer_active = TRUE; // End of process. end_process = 1; } break; case TMODE_PDTCH_INFO: // TCH result messages. //----------------------- { // Check if RX stats done in PDTCH if (l1_config.tmode.rf_params.mon_report == 0) { BOOL done; // loop and stats management done within this function l1tm_stats_pdtch_confirm((T_TMODE_PDTCH_INFO *) (msg->SigP)); done = l1tm_is_rx_counter_done(); if (done == 1) // if done, send stop TBFs { // Rise transfer parameter semaphore to prevent L1S to use partial configuration. l1pa_l1ps_com.transfer.semaphore = TRUE; // Enables the TBF release processing in L1S. l1pa_l1ps_com.transfer.tbf_release_param.tbf_release_cmd = TRUE; // Download msg info into L1PA_L1PS_COM. l1pa_l1ps_com.transfer.tbf_release_param.released_tbf = BOTH_TBF; // Clear transfer parameter semaphore to let L1S use the new parameters. l1pa_l1ps_com.transfer.semaphore = FALSE; } } // end of process end_process = 1; } break; case L1C_FB_INFO: // MON result messages. //----------------------- { // Check if RX stats done in Monitor channel if (l1_config.tmode.rf_params.mon_report == 1) { BOOL done; // loop and stats management done within this function l1tm_stats_mon_confirm( (T_TMODE_FB_CON*) ((T_L1C_FB_INFO *) (msg->SigP))); done = l1tm_is_rx_counter_done(); if (done == 1) // if done, send stop TBFs { // Rise transfer parameter semaphore to prevent L1S to use partial configuration. l1pa_l1ps_com.transfer.semaphore = TRUE; // Enables the TBF release processing in L1S. l1pa_l1ps_com.transfer.tbf_release_param.tbf_release_cmd = TRUE; // Download msg info into L1PA_L1PS_COM. l1pa_l1ps_com.transfer.tbf_release_param.released_tbf = BOTH_TBF; // Clear transfer parameter semaphore to let L1S use the new parameters. l1pa_l1ps_com.transfer.semaphore = FALSE; } } // end of process end_process = 1; } break; case TMODE_STOP_RX_TX: // TBF Release. //------------- { // Rise transfer parameter semaphore to prevent L1S to use partial configuration. l1pa_l1ps_com.transfer.semaphore = TRUE; // Enables the TBF release processing in L1S. l1pa_l1ps_com.transfer.tbf_release_param.tbf_release_cmd = TRUE; // Download msg info into L1PA_L1PS_COM. l1pa_l1ps_com.transfer.tbf_release_param.released_tbf = BOTH_TBF; // Clear transfer parameter semaphore to let L1S use the new parameters. l1pa_l1ps_com.transfer.semaphore = FALSE; // end of process. end_process = 1; } break; case L1P_TBF_RELEASED: // TBF has been release by L1S. { // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; // Reset transfer active state l1tm.tmode_state.packet_transfer_active = FALSE; // Restore stats bitmap l1_config.tmode.stats_config.stat_gprs_slots = stat_gprs_slots; #if (L1_12NEIGH ==1) l1a_l1s_com.l1s_en_task[NSYNC] = TASK_DISABLED; // Disable neighbour sync 0. l1a_l1s_com.nsync.list[0].status = NSYNC_FREE; //Used by l1s_schedule_tasks in l1_sync #endif // Step in state machine. *state = RESET; // End of process. end_process = 1; } break; default: // End of process. //---------------- { end_process = 1; } } // end of switch(SignalCode) } // end of case WAIT_MSG. } // end of "switch". } // end of "while" } // end of procedure. #endif #if ((L1_STEREOPATH == 1) && (OP_L1_STANDALONE == 1)) /*----------------------------------------------------------------*/ /* l1a_tmode_audio_stereopath_process() */ /*----------------------------------------------------------------*/ /* */ /* Description: */ /* ------------ */ /* This function is a state machine which handles the */ /* stereopath feature. */ /* */ /* Starting messages: TMODE_AUDIO_STEREOPATH_DRV_START_REQ */ /* */ /* Result messages (input): L1_STEREOPATH_DRV_START_CON */ /* */ /* Result messages (output): TMODE_AUDIO_STEREOPATH_DRV_START_CON */ /* */ /* Reset messages (input): none */ /* */ /* Stop message (input): TMODE_AUDIO_STEREOPATH_DRV_STOP_REQ */ /* L1_STEREOPATH_DRV_STOP_CON */ /* */ /* Stop message (output): TMODE_AUDIO_STEREOPATH_DRV_STOP_CON */ /* */ /* Rem: */ /* ---- */ /* */ /*----------------------------------------------------------------*/ void l1a_tmode_audio_stereopath_process(xSignalHeaderRec *msg) { #if (CODE_VERSION == NOT_SIMULATION) enum states { RESET = 0, WAIT_START_REQ = 1, WAIT_START_CON = 2, WAIT_STOP = 3, WAIT_DSP_STOP = 4 }; UWORD8 *state = &l1a.state[TMODE_AUDIO_STEREOPATH_DRV_STATE]; UWORD32 SignalCode = msg->SignalCode; static UWORD8 previous_config = 0; BOOL end_process = 0; while(!end_process) { switch(*state) { case RESET: { // initialize global variable l1tm.stereopath.stereopath_source_timeout = 0; l1tm.stereopath.stereopath_dest_timeout = 0; l1tm.stereopath.stereopath_drop = 0; l1tm.stereopath.stereopath_frame = 0; l1tm.stereopath.stereopath_block = 0; l1tm.stereopath.stereopath_half_block = 0; l1tm.stereopath.stereopath_current_sample = 0; l1tm.stereopath.stereopath_buffer_number = 0; // initialize ndb stp_drv_ndb->d_cport_api_dma_install = 0; stp_drv_ndb->d_cport_api_dma_channel = 0; stp_drv_ndb->d_cport_api_dma_rootcause = 0; // Init DSP background l1s_dsp_com.dsp_ndb_ptr->a_background_tasks[C_BGD_STP_DRV] = (API)((C_BGD_STP_DRV<<11) | 1); if (l1s_dsp_com.dsp_ndb_ptr->d_max_background<(C_BGD_STP_DRV+1)) l1s_dsp_com.dsp_ndb_ptr->d_max_background=(API)(C_BGD_STP_DRV+1); *state = WAIT_START_REQ; } break; case WAIT_START_REQ: { if (SignalCode == TMODE_AUDIO_STEREOPATH_START_REQ) { // receive a request to start stereopath T_TMODE_AUDIO_STEREOPATH_START_REQ* tmode_audio_sp_conf_ptr; // Flag msg received l1tm.tm_msg_received = TRUE; /******************************************************************/ /**************** GET STEREOPATH PARAMETERS ***********************/ /******************************************************************/ if (((T_TMODE_AUDIO_STEREOPATH_START_REQ *)(msg->SigP))->configuration == AUDIO_SP_SELF_CONF) { // no use of a predefined configuration, we have to get parameters from the message tmode_audio_sp_conf_ptr = ((T_TMODE_AUDIO_STEREOPATH_START_REQ *)(msg->SigP)); } else { UWORD8 conf_index = 0; // use of a predefined configuration, we have to get parameters from the constant config tmode_audio_sp_conf_ptr = (T_TMODE_AUDIO_STEREOPATH_START_REQ *) tmode_audio_sp_conf[conf_index]; while ((tmode_audio_sp_conf_ptr != NULL) && (conf_index < NB_MAX_STEREOPATH_CONFIG)) { if (tmode_audio_sp_conf_ptr->configuration == ((T_TMODE_AUDIO_STEREOPATH_START_REQ *)(msg->SigP))->configuration) break; tmode_audio_sp_conf_ptr = (T_TMODE_AUDIO_STEREOPATH_START_REQ *) tmode_audio_sp_conf[++conf_index]; } } if (tmode_audio_sp_conf_ptr == NULL) { // unknow configuration identifier --> use message parameters tmode_audio_sp_conf_ptr = ((T_TMODE_AUDIO_STEREOPATH_START_REQ *)(msg->SigP)); } // Download the stereopath description in the l1a_l1s structure. l1a_l1s_com.stereopath_drv_task.parameters.sampling_frequency = tmode_audio_sp_conf_ptr->sampling_frequency; l1a_l1s_com.stereopath_drv_task.parameters.DMA_allocation = tmode_audio_sp_conf_ptr->DMA_allocation; l1a_l1s_com.stereopath_drv_task.parameters.DMA_channel_number = tmode_audio_sp_conf_ptr->DMA_channel_number; l1a_l1s_com.stereopath_drv_task.parameters.data_type = tmode_audio_sp_conf_ptr->data_type; l1a_l1s_com.stereopath_drv_task.parameters.source_port = tmode_audio_sp_conf_ptr->source_port; l1a_l1s_com.stereopath_drv_task.parameters.element_number = tmode_audio_sp_conf_ptr->element_number; l1a_l1s_com.stereopath_drv_task.parameters.frame_number = tmode_audio_sp_conf_ptr->frame_number; l1a_l1s_com.stereopath_drv_task.parameters.mono_stereo = tmode_audio_sp_conf_ptr->mono_stereo; l1a_l1s_com.stereopath_drv_task.parameters.feature_identifier = AUDIO_SP_TESTS_ID; /******************************************************************/ /**************** CHECK ALLOCATION DSP/MCU ************************/ /******************************************************************/ if (tmode_audio_sp_conf_ptr->DMA_allocation == AUDIO_SP_DMA_ALLOC_MCU) { l1a_l1s_com.stereopath_drv_task.parameters.DMA_int_callback_fct = l1tm_stereopath_DMA_handler; } else // DMA_allocation == AUDIO_SP_DMA_ALLOC_DSP { // Update ndb stp_drv_ndb->d_cport_api_dma_install = 1; stp_drv_ndb->d_cport_api_dma_channel = l1a_l1s_com.stereopath_drv_task.parameters.DMA_channel_number; stp_drv_ndb->d_cport_api_dma_rootcause = 0; // start background task l1s_dsp_com.dsp_ndb_ptr->d_background_enable|=(API)(1<<C_BGD_STP_DRV); l1_trigger_api_interrupt(); l1a_l1s_com.stereopath_drv_task.parameters.DMA_int_callback_fct = f_dma_default_call_back_it; } /******************************************************************/ /**************** GENERATION OF THE PATTERN ***********************/ /******************************************************************/ // Reservation and generation of the pattern used to fill the buffer if (tmode_audio_sp_conf_ptr->pattern_identifier != AUDIO_SP_SILENCE_PATTERN) { l1tm.stereopath.stereopath_pattern = (WORD8 *)l1tm_stereopath_buffer; // if pattern has already been build with the same config (mp3,midi or ext audio) in the current scenario, // we don't do it again. This is to avoid to have a CPU overload during critical operation such as access or packet transfer if ((tmode_audio_sp_conf_ptr->configuration == 0) || (tmode_audio_sp_conf_ptr->configuration != previous_config)) { previous_config = tmode_audio_sp_conf_ptr->configuration; l1tm.stereopath.stereopath_nb_samples = l1tm_stereopath_get_pattern(l1tm_stereopath_sampling_freqs[tmode_audio_sp_conf_ptr->sampling_frequency], l1tm_stereopath_sin_freqs[tmode_audio_sp_conf_ptr->pattern_identifier][0], l1tm_stereopath_sin_freqs[tmode_audio_sp_conf_ptr->pattern_identifier][1], tmode_audio_sp_conf_ptr->data_type); } } else { // Silence pattern, consider just 2 samples at the value 0 l1tm.stereopath.stereopath_nb_samples = 2; l1tm.stereopath.stereopath_pattern = (WORD8 *)l1tm_stereopath_buffer; l1tm.stereopath.stereopath_pattern[0] = l1tm.stereopath.stereopath_pattern[1] = l1tm.stereopath.stereopath_pattern[2] = l1tm.stereopath.stereopath_pattern[3] = 0x0000; } /******************************************************************/ /**************** GET ADDRESS OF THE BUFFER ***********************/ /******************************************************************/ #if (CHIPSET == 15) if (tmode_audio_sp_conf_ptr->source_port == AUDIO_SP_SOURCE_EMIF) { // get an address in internal RAM l1a_l1s_com.stereopath_drv_task.parameters.source_buffer_address = (WORD8*) TM_stereo_buf_ext_mem; } if (tmode_audio_sp_conf_ptr->source_port == AUDIO_SP_SOURCE_IMIF) { // get an address in internal RAM l1a_l1s_com.stereopath_drv_task.parameters.source_buffer_address = (WORD8*) TM_stereo_buf; } if (tmode_audio_sp_conf_ptr->source_port == AUDIO_SP_SOURCE_API) { // Disable DSP trace l1s_dsp_com.dsp_ndb_ptr->d_debug_trace_type &= 0xfff0; l1s_dsp_com.dsp_ndb_ptr->d_debug_trace_type |= 0x8000; l1a_l1s_com.stereopath_drv_task.parameters.source_buffer_address = (WORD8*)API_address_dsp2mcu(C_STP_DRV_BUF_API_BASE_ADDRESS); } #else if (tmode_audio_sp_conf_ptr->source_port == AUDIO_SP_SOURCE_IMIF) { // get an address in internal RAM l1a_l1s_com.stereopath_drv_task.parameters.source_buffer_address = (WORD8*) TM_stereo_buf; } else // source_port == AUDIO_SP_SOURCE_API { // Disable DSP trace l1s_dsp_com.dsp_ndb_ptr->d_debug_trace_type &= 0xfff0; l1s_dsp_com.dsp_ndb_ptr->d_debug_trace_type |= 0x8000; l1a_l1s_com.stereopath_drv_task.parameters.source_buffer_address = (WORD8*)API_address_dsp2mcu(C_STP_DRV_BUF_API_BASE_ADDRESS); } #endif /******************************************************************/ /**************** FILL THE 2 FIRST BUFFERS ************************/ /******************************************************************/ l1tm_stereopath_fill_buffer((void*) l1a_l1s_com.stereopath_drv_task.parameters.source_buffer_address); l1tm_stereopath_fill_buffer((void*) l1a_l1s_com.stereopath_drv_task.parameters.source_buffer_address); // Start the L1S stereopath task l1a_l1s_com.stereopath_drv_task.command.start = TRUE; *state = WAIT_START_CON; } // End process end_process = 1; } break; case WAIT_START_CON: { if (SignalCode == L1_STEREOPATH_DRV_START_CON) { // Send the start confirmation message l1a_audio_send_confirmation(TMODE_AUDIO_STEREOPATH_START_CON); *state = WAIT_STOP; } // End process end_process = 1; } break; case WAIT_STOP: { if (SignalCode == TMODE_AUDIO_STEREOPATH_STOP_REQ) { if (l1a_l1s_com.stereopath_drv_task.parameters.DMA_allocation == AUDIO_SP_DMA_ALLOC_DSP) { // we first need to stop the DSP background task stp_drv_ndb->d_cport_api_dma_install = 0xFFFF; l1_trigger_api_interrupt(); *state = WAIT_DSP_STOP; } else { // Stop the L1S stereopath task l1a_l1s_com.stereopath_drv_task.command.stop = TRUE; // End process end_process = 1; } } else if (SignalCode == L1_STEREOPATH_DRV_STOP_CON) { // Reset TM msg flag // No new L1S result messages may be received before a new TM command l1tm.tm_msg_received = FALSE; free(l1tm.stereopath.stereopath_pattern); // Send the stop confirmation message l1a_audio_send_confirmation(TMODE_AUDIO_STEREOPATH_STOP_CON); *state = RESET; } else { // End process end_process = 1; } } break; case WAIT_DSP_STOP: { if (stp_drv_ndb->d_cport_api_dma_install == 0) { // stop the DSP background task l1s_dsp_com.dsp_ndb_ptr->d_background_enable&=(API)(~(1<<C_BGD_STP_DRV)); l1_trigger_api_interrupt(); // Stop the L1S stereopath task l1a_l1s_com.stereopath_drv_task.command.stop = TRUE; *state = WAIT_STOP; end_process = 1; } } break; } // switch } // while(!end_process) #endif // CODE_VERSION == NOT_SIMULATION } #endif // #if ((L1_STEREOPATH == 1) && (OP_L1_STANDALONE == 1)) #endif