Lorekeeping: allow tpudrv-leonardo.lib on Leonardo/Tango
Back in 2015 the Mother's idea was to produce a FreeCalypso development
board that would be a clone of TI Leonardo, including the original
quadband RFFE; one major additional stipulation was that this board
needed to be able to run original unmodified TCS211-20070608 firmware
with all blobs intact, with only minimal binary patches to main.lib
and tpudrv.lib. The necessary patched libs were produced at that time
in the tcs211-patches repository.
That plan was changed and we produced FCDEV3B instead, with Openmoko's
triband RFFE instead of Leonardo quadband, but when FC Magnetite started
in 2016, a TPUDRV_blob= provision was still made, allowing the possibility
of patching OM's tpudrv.lib for a restored Leonardo RFFE.
Now in 2020 we have FC Tango which is essentially a verbatim clone of
Leonardo core, including the original quadband RFFE. We have also
deblobbed our firmware so much that we have absolutely no real need
for a blob version of tpudrv.lib - but I thought it would be neat to put
the ancient TPUDRV_blob= mechanism (classic config) to its originally
intended use, just for the heck of it.
line source
+ − /************* Revision Controle System Header *************
+ − * GSM Layer 1 software
+ − * L1P_DRIVE.C
+ − *
+ − * Filename l1p_driv.c
+ − * Copyright 2003 (C) Texas Instruments
+ − *
+ − ************* Revision Controle System Header *************/
+ −
+ − #define L1P_DRIVE_C
+ −
+ − #include "l1_macro.h"
+ − #include "l1_confg.h"
+ −
+ − #if L1_GPRS
+ − #if (CODE_VERSION == SIMULATION)
+ − #include <string.h>
+ − #include "l1_types.h"
+ − #include "sys_types.h"
+ − #include "l1_const.h"
+ − #include "l1_time.h"
+ − #if TESTMODE
+ − #include "l1tm_defty.h"
+ − #endif
+ − #if (AUDIO_TASK == 1)
+ − #include "l1audio_const.h"
+ − #include "l1audio_cust.h"
+ − #include "l1audio_defty.h"
+ − #endif
+ − #if (L1_GTT == 1)
+ − #include "l1gtt_const.h"
+ − #include "l1gtt_defty.h"
+ − #endif
+ − #if (L1_MP3 == 1)
+ − #include "l1mp3_defty.h"
+ − #endif
+ − #if (L1_MIDI == 1)
+ − #include "l1midi_defty.h"
+ − #endif
+ − #include "l1_defty.h"
+ − #include "l1_varex.h"
+ − #include "cust_os.h"
+ − #include "l1_msgty.h"
+ − #if L2_L3_SIMUL
+ − #include "hw_debug.h"
+ − #endif
+ −
+ − #include "l1p_cons.h"
+ − #include "l1p_msgt.h"
+ − #include "l1p_deft.h"
+ − #include "l1p_vare.h"
+ − #include "l1p_tabs.h"
+ −
+ − #include "sim_cons.h"
+ − #include "sim_def.h"
+ − extern T_hw FAR hw;
+ − #include "l1_proto.h"
+ −
+ − #else
+ −
+ − #include <string.h>
+ − #include "l1_types.h"
+ − #include "sys_types.h"
+ − #include "l1_const.h"
+ − #include "l1_time.h"
+ −
+ − #if TESTMODE
+ − #include "l1tm_defty.h"
+ − #endif
+ − #if (AUDIO_TASK == 1)
+ − #include "l1audio_const.h"
+ − #include "l1audio_cust.h"
+ − #include "l1audio_defty.h"
+ − #endif
+ − #if (L1_GTT == 1)
+ − #include "l1gtt_const.h"
+ − #include "l1gtt_defty.h"
+ − #endif
+ − #if (L1_MP3 == 1)
+ − #include "l1mp3_defty.h"
+ − #endif
+ − #if (L1_MIDI == 1)
+ − #include "l1midi_defty.h"
+ − #endif
+ − #include "l1_defty.h"
+ − #include "l1_varex.h"
+ − #include "cust_os.h"
+ − #include "l1_msgty.h"
+ − #if L2_L3_SIMUL
+ − #include "hw_debug.h"
+ − #endif
+ −
+ − #include "l1p_cons.h"
+ − #include "l1p_msgt.h"
+ − #include "l1p_deft.h"
+ − #include "l1p_vare.h"
+ − #include "l1p_tabs.h"
+ −
+ − #include "l1_proto.h"
+ − #include "tpudrv.h"
+ −
+ − #endif
+ −
+ − #if(RF_FAM == 61)
+ − #include "l1_rf61.h"
+ − #include "tpudrv61.h"
+ − #include "l1_ctl.h"
+ − #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_afc (UWORD16 afc_value, UWORD8 win_id);
+ −
+ − #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3) || (RF_FAM == 61) )
+ − UWORD16 Cust_get_pwr_data(UWORD8 txpwr, UWORD16 radio_freq
+ − #if(REL99 && FF_PRF)
+ − ,UWORD8 number_uplink_timeslot
+ − #endif
+ − );
+ − #endif
+ − void Cust_get_ramp_tab(API *a_ramp, UWORD8 txpwr_ramp_up, UWORD8 txpwr_ramp_down, UWORD16 radio_freq);
+ −
+ − BOOL l1ps_swap_iq_ul (UWORD16 radio_freq);
+ − BOOL l1ps_swap_iq_dl (UWORD16 radio_freq);
+ − #if (L1_MADC_ON == 1)
+ − #if (RF_FAM == 61)
+ − void l1pdmacro_rx_up (UWORD16 radio_freq,UWORD8 adc_active, UWORD8 csf_filter_choice
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,UWORD8 saic_flag
+ − #endif /* NEW_SNR_THRESHOLD == 1*/
+ − );
+ − #endif
+ − #else /* RF_FAM == 61*/
+ − void l1pdmacro_rx_up (UWORD16 radio_freq);
+ − #endif
+ − void l1pdmacro_rx_down (UWORD16 radio_freq, UWORD8 num_rx, BOOL rx_done_flag);
+ − void l1pdmacro_tx_up (UWORD16 radio_freq);
+ − void l1pdmacro_tx_down (UWORD16 radio_freq, WORD16 time, BOOL tx_flag, UWORD8 timing_advance,UWORD8 adc_active);
+ − void l1pdmacro_tx_synth(UWORD16 radio_freq);
+ − void l1pdmacro_anchor (WORD16 time);
+ −
+ − void l1dmacro_rx_synth(UWORD16 radio_freq);
+ − void l1dmacro_agc(UWORD16 radio_freq, WORD8 agc_value, UWORD8 lna_off
+ − #if (RF_FAM == 61)
+ − ,UWORD8 if_ctl
+ − #endif
+ − );
+ − #if (CODE_VERSION == SIMULATION)
+ − void l1dmacro_rx_ms (UWORD16 arfcn, BOOL rxnb_select);
+ − #else
+ − #if (L1_MADC_ON == 1)
+ − #if (RF_FAM == 61)
+ − void l1dmacro_rx_ms (UWORD16 arfcn,UWORD8 adc_active);
+ − #endif
+ − #else
+ − void l1dmacro_rx_ms (UWORD16 arfcn);
+ − #endif
+ − #endif
+ − void l1pdmacro_it_dsp_gen(WORD16 time);
+ −
+ − /*-------------------------------------------------------*/
+ − /* Prototypes of functions defined in this file. */
+ − /*-------------------------------------------------------*/
+ − // TPU Drivers...
+ −
+ −
+ − // DSP Drivers...
+ − void l1pddsp_synchro (UWORD8 switch_mode, UWORD8 camp_timeslot);
+ − void l1pddsp_idle_prach_data (BOOL polling, UWORD8 cs_type, UWORD16 channel_request_data,
+ − UWORD8 bsic, UWORD16 radio_freq);
+ − void l1pddsp_idle_prach_power (UWORD8 txpwr, UWORD16 radio_freq, UWORD8 ts);
+ − void l1pddsp_single_tx_block (UWORD8 burst_nb, UWORD8 *data, UWORD8 tsc,
+ − UWORD16 radio_freq);
+ − #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
+ − void l1pddsp_transfer_mslot_ctrl (UWORD8 burst_nb, UWORD8 dl_bitmap, UWORD8 ul_bitmap,
+ − UWORD8 *usf_table, UWORD8 mac_mode, UWORD8 *ul_buffer_index,
+ − UWORD8 tsc, UWORD16 radio_freq, UWORD8 synchro_timeslot,
+ − #if FF_L1_IT_DSP_USF
+ − UWORD8 dsp_usf_interrupt
+ − #else
+ − UWORD8 usf_vote_enable
+ − #endif
+ − );
+ − void l1pddsp_transfer_mslot_power (UWORD8 *txpwr, UWORD16 radio_freq, UWORD8 ul_bitmap);
+ − void l1pddsp_ul_ptcch_data (UWORD8 cs_type, UWORD16 channel_request_data, UWORD8 bsic,
+ − UWORD16 radio_freq, UWORD8 timeslot_no);
+ − void l1pddsp_interf_meas_ctrl (UWORD8 nb_meas_req);
+ − void l1pddsp_transfer_meas_ctrl (UWORD8 meas_position);
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1pd_afc() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − void l1pd_afc(void)
+ − {
+ − #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
+ − l1ddsp_load_afc(l1s.afc);
+ − #endif
+ − #if (RF_FAM == 61)
+ − l1dtpu_load_afc(l1s.afc);
+ − #endif
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1pdtpu_interf_meas() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − UWORD8 l1pdtpu_interf_meas(UWORD16 radio_freq,
+ − WORD8 agc,
+ − UWORD8 lna_off,
+ − UWORD8 meas_bitmap,
+ − UWORD32 offset_serv,
+ − UWORD16 win_id,
+ − UWORD8 synchro_ts
+ − #if (RF_FAM == 61)
+ − ,UWORD8 if_ctl
+ − #endif
+ − )
+ − {
+ − UWORD8 bit_mask = 0x80;
+ − UWORD8 ts;
+ − BOOL rf_programmed = FALSE;
+ − UWORD8 count = 0;
+ −
+ − if(!win_id)
+ − {
+ − // Nothing programmed yet, we must avoid Mirror effect in Ctrl phase.
+ − l1pdmacro_anchor(l1_config.params.rx_change_offset_time);
+ − }
+ −
+ − for (ts=0; ts<8; ts++)
+ − {
+ − // the bitmap corresponds to that of the idle frame of the network!!!
+ − #if ((CHIPSET==3)||(CHIPSET == 4))
+ − // limitation of 5 measurements for SAMSON (TPU RAM size limitation)
+ − if((meas_bitmap & bit_mask)&&(count <= 4))
+ − #else
+ − if(meas_bitmap & bit_mask)
+ − #endif
+ − {
+ − UWORD16 local_win_id;
+ − UWORD16 offset;
+ − WORD16 when;
+ − UWORD16 offset_chg;
+ −
+ − if((ts>synchro_ts) && (count==0))
+ − {
+ − // The 1st Work does not contain any Interf meas.
+ − // We must ovoid a possible Mirror effect for the rest of TS.
+ − l1pdmacro_anchor(l1_config.params.rx_change_offset_time);
+ − }
+ −
+ − // Increment nbr of meas. programmed.
+ − count++;
+ −
+ − local_win_id = (8 - synchro_ts + ts) * BP_SPLIT;
+ − if(local_win_id >= (BP_SPLIT * 8)) local_win_id -= BP_SPLIT * 8; // Modulo.
+ −
+ − // Compute offset
+ − offset_chg = ((local_win_id * BP_DURATION) >> BP_SPLIT_PW2);
+ − offset = offset_serv + offset_chg;
+ − if(offset >= TPU_CLOCK_RANGE) offset -= TPU_CLOCK_RANGE;
+ −
+ − if(!rf_programmed)
+ − {
+ − // Compute offset change timing
+ − when = offset_chg +
+ − PROVISION_TIME -
+ − l1_config.params.rx_synth_setup_time -
+ − EPSILON_OFFS;
+ −
+ − if(when < 0) when += TPU_CLOCK_RANGE;
+ −
+ − // Program TPU scenario
+ − l1dmacro_offset (offset, when); // change TPU offset according to win_id
+ − l1dmacro_rx_synth (radio_freq); // pgme SYNTH.
+ − #if (RF_FAM !=61)
+ − l1dmacro_agc (radio_freq, agc,lna_off); // pgme AGC.
+ − #endif
+ −
+ − #if (RF_FAM == 61)
+ − l1dmacro_agc (radio_freq, agc,lna_off, if_ctl); // pgme AGC.
+ − #endif
+ −
+ − rf_programmed = TRUE;
+ − }
+ − else
+ − {
+ − // Compute offset change timing
+ − when = offset_chg - BP_DURATION + PROVISION_TIME + PW_ACQUIS_DURATION + 20;
+ − if(when < 0) when += TPU_CLOCK_RANGE;
+ −
+ − // Program TPU scenario
+ − l1dmacro_offset (offset, when); // change TPU offset according to win_id
+ − }
+ −
+ − #if (CODE_VERSION == SIMULATION)
+ − l1dmacro_rx_ms (radio_freq, 1); // pgm PWR acquisition.
+ − #else
+ − #if (L1_MADC_ON == 1)
+ − #if (RF_FAM == 61)
+ − l1dmacro_rx_ms (radio_freq,INACTIVE); // pgm PWR acquisition.
+ − #endif
+ − #else
+ − l1dmacro_rx_ms (radio_freq); // pgm PWR acquisition.
+ − #endif
+ − #endif
+ −
+ − l1dmacro_offset (offset_serv, IMM); // restore offset
+ − }
+ −
+ − bit_mask >>= 1;
+ −
+ − } // for(ts...
+ −
+ − return(count);
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1dtpu_serv_rx() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* rx_id: range 0-7, first slot of RX group */
+ − /* rx_group_id: used in case |RX| |RX| */
+ − /* */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − void l1pdtpu_serv_rx_nb(UWORD16 radio_freq, UWORD8 agc, UWORD8 lna_off,
+ − UWORD8 rx_id, UWORD32 offset_serv, UWORD8 num_rx,
+ − UWORD8 rx_group_id, BOOL rx_done_flag,UWORD8 adc_active
+ − #if (RF_FAM == 61)
+ − ,UWORD8 csf_filter_choice
+ − ,UWORD8 if_ctl
+ − #endif
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,UWORD8 saic_flag
+ − #endif /* NEW_SNR_THRESHOLD*/
+ − )
+ − {
+ − UWORD16 offset;
+ −
+ − #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][rx_group_id-1]=rx_id;
+ − hw.num_rx[tpu_w_page][rx_group_id-1]=num_rx;
+ − hw.rx_group_id[tpu_w_page]=rx_group_id;
+ − #endif
+ −
+ − offset = offset_serv + (rx_id * BP_DURATION);
+ − if(offset >= TPU_CLOCK_RANGE) offset -= TPU_CLOCK_RANGE;
+ −
+ − if (rx_group_id == 1)
+ − {
+ − // Time tracking.
+ − l1dmacro_synchro (l1_config.params.rx_change_synchro_time, offset_serv); // Adjust serving OFFSET.
+ −
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET)
+ − buffer_trace(3, 0x43, offset_serv, l1s.actual_time.fn, 0);
+ − #endif
+ − #endif
+ −
+ − // Change offset to align on RX.
+ − l1dmacro_offset(offset, IMM);
+ −
+ − // Program Synth.
+ − // Program ADC measurement
+ − // Program AGC.
+ − l1dmacro_rx_synth(radio_freq);
+ − if(adc_active == ACTIVE)
+ − l1dmacro_adc_read_rx();
+ −
+ − l1dmacro_agc (radio_freq, agc, lna_off
+ − #if (RF_FAM == 61)
+ − ,if_ctl
+ − #endif
+ − );
+ − }
+ − else
+ − {
+ − // Change offset to align on RX.
+ − l1dmacro_offset(offset, IMM); // Change offset to align on RX.
+ − }
+ −
+ − l1pdmacro_rx_up (radio_freq
+ − #if (RF_FAM == 61)
+ − ,adc_active
+ − ,csf_filter_choice
+ − #endif
+ − #if (NEW_SNR_THRESHOLD == 1)
+ − ,saic_flag
+ − #endif /* NEW_SNR_THRESHOLD*/
+ −
+ − ); // RX window opened.
+ − l1pdmacro_rx_down(radio_freq, num_rx, rx_done_flag); // RX window closed.
+ −
+ − // Restore offset to synchro value.
+ − l1dmacro_offset (offset_serv, IMM);
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1dtpu_serv_tx() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
+ − #ifndef ABB_RAMP_UP_TIME //Flexi ABB Delays defines it in tpudrvXX.h
+ − #define ABB_RAMP_UP_TIME 32 // maximum time for ramp up
+ − #endif
+ −
+ − #ifndef ABB_RAMP_DELAY//Flexi ABB Delays defines it in tpudrvXX.h
+ − #define ABB_RAMP_DELAY 6 // minimum ramp delay APCDEL
+ − #endif
+ −
+ − #ifndef ABB_BULON_HOLD_TIME //Flexi ABB Delays defines it in tpudrvXX.h
+ − #define ABB_BULON_HOLD_TIME 32 // min. hold time for BULON after BULENA down
+ − #endif
+ −
+ −
+ − #endif
+ − void l1pdtpu_serv_tx(UWORD16 radio_freq,
+ − UWORD8 timing_advance,
+ − UWORD32 offset_serv,
+ − UWORD8 tx_id,
+ − UWORD8 num_tx,
+ − UWORD8 tx_group_id,
+ − UWORD8 switch_flag,
+ − BOOL burst_type,
+ − BOOL rx_flag,
+ − UWORD8 adc_active)
+ − {
+ − WORD16 time;
+ − UWORD32 offset_tx;
+ − UWORD32 timing_advance_in_qbit = (UWORD32)timing_advance << 2;
+ − #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3) || (RF_FAM == 61))
+ − UWORD16 apcdel1_data, apcdel1_data_up;
+ − #endif
+ − UWORD8 i;
+ − static UWORD8 static_switch_flag = 0;
+ −
+ − #if (CODE_VERSION == SIMULATION)
+ − UWORD32 tpu_w_page;
+ −
+ − if (hw.tpu_r_page==0)
+ − tpu_w_page=1;
+ − else
+ − tpu_w_page=0;
+ −
+ − hw.tx_id[tpu_w_page][tx_group_id-1]=tx_id;
+ − hw.num_tx[tpu_w_page][tx_group_id-1]=num_tx;
+ − hw.tx_group_id[tpu_w_page]=tx_group_id;
+ − #endif
+ −
+ − // Reset timing advance if TA_ALGO not enabled.
+ − #if !TA_ALGO
+ − timing_advance_in_qbit = 0;
+ − #endif
+ −
+ − // In case another group of TX bursts is called, the previous slot was a hole
+ − // An IT has to be generated to the DSP so that ramps and power level are reloaded
+ − // This does not apply to combinations of PRACH and TX NB
+ − if ((tx_group_id > 1) && (!static_switch_flag))
+ − {
+ − // exact timing for generation of IT during hole not required but
+ − // time > time of previous ramp down (BULENA -> BULON down = 32 qb) + margin (10 qb)
+ − #if (RF_FAM != 61)
+ − time = TX_TABLE[tx_id-1] + PROVISION_TIME + ABB_BULON_HOLD_TIME + 10
+ − - l1_config.params.prg_tx_gsm;
+ − #endif
+ −
+ − #if (RF_FAM == 61)
+ − time = TX_TABLE[tx_id-1] + PROVISION_TIME + APC_RAMP_DOWN_TIME + 10
+ − - l1_config.params.prg_tx_gsm;
+ − #endif
+ −
+ − if (burst_type == TX_NB_BURST)
+ − time -= timing_advance_in_qbit; // time can never be negative here
+ −
+ − l1pdmacro_it_dsp_gen(time);
+ − }
+ −
+ −
+ − if (tx_group_id == 1)
+ − {
+ − #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
+ − //MS TX, set ABB in MS mode
+ − #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37)
+ − // ABB set to MS mode if |TX|TX|.., |TX|PRACH|, |PRACH|TX| or |PRACH|PRACH|
+ − // switch_flag is set for the first burst of TX/PRACH or PRACH/PRACH combinations
+ − // MS mode in ABB must be maintained for second burst (static_switch_flag)
+ − if ((num_tx > 1) || (switch_flag) || (static_switch_flag))
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_bbctrl_gprs = l1_config.params.bbctrl | B_MSLOT;
+ − else
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_bbctrl_gprs = l1_config.params.bbctrl;
+ − #endif
+ − #endif
+ − }
+ − else
+ − {
+ − // handle special case |TX| |TX|TX|
+ − #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
+ − //MS TX, set ABB in MS mode
+ − #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37)
+ − if ((num_tx > 1) || (switch_flag) || (static_switch_flag))
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_bbctrl_gprs = l1_config.params.bbctrl | B_MSLOT;
+ − #endif
+ − #endif
+ − }
+ −
+ − // Compute offset value for TX.
+ − // PRG_TX has become variable, no longer contained in TIME_OFFSET_TX !
+ − if ((burst_type == TX_NB_BURST) || (switch_flag==1))
+ − {
+ − offset_tx = offset_serv + TX_TABLE[tx_id] + PROVISION_TIME
+ − - l1_config.params.prg_tx_gsm - timing_advance_in_qbit;
+ − }
+ − else
+ − {
+ − offset_tx = offset_serv + TX_TABLE[tx_id] + PROVISION_TIME
+ − - l1_config.params.prg_tx_gsm;
+ − }
+ −
+ − // offset_tx mod 5000
+ − if (offset_tx >= TPU_CLOCK_RANGE)
+ − offset_tx -= TPU_CLOCK_RANGE;
+ −
+ − if(rx_flag == TRUE)
+ − {
+ − time = offset_tx -
+ − l1_config.params.tx_synth_setup_time -
+ − EPSILON_OFFS
+ − - offset_serv;
+ − if ((burst_type == TX_NB_BURST) || (switch_flag==1))
+ − time += timing_advance_in_qbit - TA_MAX;
+ − }
+ − else
+ − time = TPU_CLOCK_RANGE - EPSILON_SYNC;
+ −
+ − if (time < 0)
+ − time += TPU_CLOCK_RANGE;
+ −
+ − if (!static_switch_flag)
+ − l1dmacro_offset (offset_tx, (WORD32) time); // load OFFSET for TX before each burst.
+ −
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET)
+ − buffer_trace(2, offset_tx,l1s.actual_time.fn,0,0);
+ − #endif
+ − #endif
+ −
+ − time=0;
+ −
+ − // program PLL only if no TX control carried out in same frame: |TX| |TX|TX| possible
+ − // |PRACH|TX|, |TX|PRACH| or |PRACH|PRACH| also possible
+ − if (tx_group_id == 1)
+ − {
+ − l1pdmacro_tx_synth(radio_freq); // load SYNTH.
+ − }
+ −
+ − if (!static_switch_flag) // window opened for previous time slot (TX/PRACH or PRACH/PRACH)
+ − l1pdmacro_tx_up(radio_freq); // TX window opened
+ −
+ −
+ − #if (CODE_VERSION == SIMULATION)
+ − if (burst_type == TX_RA_BURST)
+ − {
+ − time += l1_config.params.tx_ra_duration;
+ − }
+ − else
+ − {
+ − if (num_tx > 1)
+ − // num_tx * BP_DURATION
+ − time += TX_TABLE[num_tx - 1] + l1_config.params.tx_nb_duration;
+ − else
+ − time += l1_config.params.tx_nb_duration;
+ − }
+ − #else
+ − #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
+ − // Read APCDEL1 register DELU(4:0): delay of ramp up start, DELD (9:5) delay of ramp down start
+ − // This value is used for computations in MS TX or TX/PRACH combinations
+ − // This value is not modified by the computations
+ − apcdel1_data = (l1s_dsp_com.dsp_ndb_ptr->d_apcdel1 >> 6) & 0x03ff;
+ − apcdel1_data_up = apcdel1_data & 0x001f; //delay of ramp up start
+ − #endif
+ −
+ − #if (RF_FAM == 61)
+ − // Read APCDEL1 register DELU(4:0): delay of ramp up start, DELD (9:5) delay of ramp down start
+ − // This value is used for computations in MS TX or TX/PRACH combinations
+ − // This value is not modified by the computations
+ − apcdel1_data = (l1s_dsp_com.dsp_ndb_ptr->d_apcdel1) & 0x03ff;
+ − apcdel1_data_up = apcdel1_data & 0x001f; //delay of ramp up start
+ − #endif
+ −
+ − if (!switch_flag)
+ − {
+ − if (burst_type == TX_NB_BURST)
+ − {
+ − // If PRACH precedes TX normal burst(s) we have to add BP_DURATION
+ − if (static_switch_flag)
+ − time += BP_DURATION;
+ −
+ − // generate DSP IT for each TX slot after ramp up
+ − // Margin:
+ − // ABB_RAMP_DELAY = 4*1.5bits internal ABB delay BULENA ON -> ramp up
+ − // apcdel1_data_up = additional delay BULENA ON -> ramp up
+ − // ABB_RAMP_UP_TIME: maximum time for ramp up: 16 coeff.
+ − // 10 qbits of additional margin
+ − #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
+ − for (i=0; i<num_tx; i++)
+ − l1pdmacro_it_dsp_gen(time + ABB_RAMP_DELAY + ABB_RAMP_UP_TIME + i*BP_DURATION + apcdel1_data_up + 10);
+ − #endif
+ −
+ − #if (RF_FAM == 61)
+ − for (i=0; i<num_tx; i++)
+ − l1pdmacro_it_dsp_gen(time + APC_RAMP_DELAY + APC_RAMP_UP_TIME + i*BP_DURATION + apcdel1_data_up + 10);
+ − #endif
+ −
+ −
+ − if (num_tx > 1)
+ − // (num_tx - 1) * BP_DURATION + normal burst duration
+ − time += TX_TABLE[num_tx - 1] + l1_config.params.tx_nb_duration - (num_tx - 1);
+ − else
+ − time += l1_config.params.tx_nb_duration;
+ − }
+ − else //PRACH
+ − {
+ − // If TX NB precedes PRACH we have to add BP_DURATION and TA (in qbits)
+ − if (static_switch_flag == 1)
+ − {
+ − if (timing_advance_in_qbit > 240) // clip TA, cf. comment below
+ − timing_advance_in_qbit = 240;
+ − time += BP_DURATION + timing_advance_in_qbit;
+ − }
+ − // If PRACH precedes PRACH we have to add BP_DURATION
+ − else if (static_switch_flag == 2)
+ − time += BP_DURATION ;
+ −
+ − #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
+ − l1pdmacro_it_dsp_gen(time + ABB_RAMP_DELAY + ABB_RAMP_UP_TIME + apcdel1_data_up + 10);
+ − #endif
+ −
+ − #if (RF_FAM == 61)
+ − l1pdmacro_it_dsp_gen(time + APC_RAMP_DELAY + APC_RAMP_UP_TIME + apcdel1_data_up + 10);
+ − #endif
+ −
+ − time += l1_config.params.tx_ra_duration;
+ − }
+ −
+ − }
+ − else if (switch_flag == 1) // |TX|PRACH| or |PRACH|TX|
+ − {
+ − #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)
+ − // => ABB windows are opened as for TX_NB in MS mode
+ − // => Ramp up start of PRACH is delayed inside this window by the TA of the TX_NB
+ − // => DSP inserts dummy bits such that ramp and modulation match
+ − // Rem.: the TA passed for the PRACH is the one for the following TX_NB!!!
+ − #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3)) || (RF_FAM == 61)
+ − // In combinations of TX_NB and PRACH apcdel1_bis and apcdel2_bis apply to the PRACH
+ − UWORD16 apcdel1_bis_data, apcdel1_bis_data_up, apcdel2_bis_data_up, prach_delay;
+ − API d_ctrl_abb_gprs;
+ −
+ − // clip TA (in qbit): max. TA supported = BP_DURATION - PRACH duration - max. ramp time
+ − // = 625 - 88*4 - 32 = 241
+ − if (timing_advance_in_qbit > 240)
+ − timing_advance_in_qbit = 240;
+ −
+ − prach_delay = apcdel1_data_up + timing_advance_in_qbit;
+ − apcdel1_bis_data_up = prach_delay & 0x001f;
+ − apcdel2_bis_data_up = (prach_delay >> 5) & 0x001f;
+ −
+ − // For ramp down delay we need to keep the original value from APCDEL1 (bits 9:5)
+ − // APCDEL2 default value is '0'
+ − apcdel1_bis_data = apcdel1_bis_data_up | (apcdel1_data & 0x03e0);
+ −
+ − #if(RF_FAM != 61)
+ − l1s_dsp_com.dsp_ndb_ptr->d_apcdel1_bis = (apcdel1_bis_data << 6) | 0x04;
+ − l1s_dsp_com.dsp_ndb_ptr->d_apcdel2_bis = (apcdel2_bis_data_up << 6) | 0x34;
+ − #else
+ − l1s_dsp_com.dsp_ndb_ptr->d_apcdel1_bis = (apcdel1_bis_data );
+ − l1s_dsp_com.dsp_ndb_ptr->d_apcdel2_bis = (apcdel2_bis_data_up);
+ − #endif
+ −
+ − if (burst_type == TX_RA_BURST) // |PRACH|TX|
+ − {
+ −
+ − #if(RF_FAM != 61)
+ − l1pdmacro_it_dsp_gen(time + ABB_RAMP_DELAY + ABB_RAMP_UP_TIME + prach_delay + 10);
+ − #else
+ − l1pdmacro_it_dsp_gen(time + APC_RAMP_DELAY + APC_RAMP_UP_TIME + prach_delay + 10);
+ − #endif
+ − // apcdel1_bis, apcdel2_bis must be programmed for the current ts (PRACH)
+ − // here we need to overwrite (mask) bits for APCDEL1, APCDEL2 programming done in l1pddsp_transfer_mslot_power()
+ − d_ctrl_abb_gprs = l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[tx_id];
+ − d_ctrl_abb_gprs |= ((1 << B_BULRAMPDEL_BIS) | (1 << B_BULRAMPDEL2_BIS));
+ − d_ctrl_abb_gprs &= ~((1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2));
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[tx_id] = d_ctrl_abb_gprs;
+ − }
+ − else // |TX|PRACH|
+ − {
+ − #if(RF_FAM != 61)
+ − l1pdmacro_it_dsp_gen(time + ABB_RAMP_DELAY + ABB_RAMP_UP_TIME + apcdel1_data_up + 10);
+ − #else
+ − l1pdmacro_it_dsp_gen(time + APC_RAMP_DELAY + APC_RAMP_UP_TIME + apcdel1_data_up + 10);
+ − #endif
+ −
+ − // apcdel1_bis, apcdel2_bis must be programmed for the next ts (PRACH)
+ − d_ctrl_abb_gprs = l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[tx_id + 1];
+ − d_ctrl_abb_gprs |= ((1 << B_BULRAMPDEL_BIS) | (1 << B_BULRAMPDEL2_BIS));
+ − d_ctrl_abb_gprs &= ~((1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2));
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[tx_id + 1] = d_ctrl_abb_gprs;
+ − }
+ − #endif // ANALOG
+ −
+ − static_switch_flag = 1;
+ −
+ − #endif // DSP == 33 || DSP == 34 || (DSP == 36) || (DSP == 37)
+ − }
+ − else if (switch_flag == 2) // |PRACH|PRACH|
+ − // Combination handled by programming ABB with MS mode = 1
+ − // => first burst length of first PRACH = BP_DURATION
+ − {
+ − #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
+ − l1pdmacro_it_dsp_gen(time + ABB_RAMP_DELAY + ABB_RAMP_UP_TIME + apcdel1_data_up + 10);
+ − #endif
+ −
+ − #if (RF_FAM == 61)
+ − l1pdmacro_it_dsp_gen(time + APC_RAMP_DELAY + APC_RAMP_UP_TIME + apcdel1_data_up + 10);
+ − #endif
+ −
+ − static_switch_flag = 2;
+ − }
+ − #endif //Codeversion
+ −
+ − // In case of combinations TX_NB/PRACH or PRACH/PRACH the TX window is kept open
+ − if (!switch_flag)
+ − {
+ − l1pdmacro_tx_down(radio_freq, time, switch_flag, timing_advance_in_qbit,adc_active); // TX window closed
+ −
+ − l1dmacro_offset (offset_serv, IMM); // Restore offset with serving value.
+ −
+ − static_switch_flag = 0;
+ − }
+ −
+ − #if L2_L3_SIMUL
+ − #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET)
+ − buffer_trace(2, offset_serv,l1s.actual_time.fn,0,0);
+ − #endif
+ − #endif
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1pddsp_synchro() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − void l1pddsp_synchro(UWORD8 switch_mode, UWORD8 camp_timeslot)
+ − {
+ − // Set "b_abort" to TRUE.
+ − l1s_dsp_com.dsp_db_w_ptr->d_ctrl_system |= (1 << B_TASK_ABORT);
+ −
+ − // Set switch mode within "b_switch_to_gprs" & "b_switch_to_gms"
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_sched_mode_gprs = (switch_mode << B_SWITCH);
+ −
+ − // In case of a switch to GPRS_SCHEDULER, last_used_txpwr is set to "NO_TXPWR"
+ − // in order to force GSM ramp programming when the MS will switch back to
+ − // GSM_SCHEDULER
+ − // Moreover, the d_win_start_gprs register must be initialized only during the
+ − // GSM->GPRS switch too.
+ − if(switch_mode == GPRS_SCHEDULER)
+ − {
+ − l1s.last_used_txpwr = NO_TXPWR;
+ −
+ − // Set camp timeslot.
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_win_start_gprs = camp_timeslot;
+ − }
+ − }
+ −
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1pddsp_idle_prach_data() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − void l1pddsp_idle_prach_data(BOOL polling,
+ − UWORD8 cs_type,
+ − UWORD16 channel_request_data,
+ − UWORD8 bsic,
+ − UWORD16 radio_freq)
+ − {
+ − UWORD16 swap_bit; // 16 bit wide to allow shift left.
+ −
+ − // UL on TS=3.
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= 0x80 >> 3;
+ −
+ − // Swap I/Q management.
+ − swap_bit = l1ps_swap_iq_ul(radio_freq);
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= swap_bit << 15;
+ −
+ − // Load UL buffer according to "polling" bit.
+ − if(polling)
+ − {
+ − // Select first UL polling buffer.
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_ul_buffer_gprs[3] = 8;
+ −
+ − // Store CS type.
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[0][0] = cs_type;
+ −
+ − // Store UL data block.
+ − if(cs_type == CS_PAB8_TYPE)
+ − {
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[0][2] = ((API)(bsic << 2)) |
+ − ((API)(channel_request_data) << 8);
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[0][3] = 0;
+ − }
+ − else
+ − {
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[0][2] = ((API)(channel_request_data) << 5);
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[0][3] = ((API)(bsic << 10));
+ − }
+ − }
+ − else
+ − {
+ − // Set "b_access_prach" to indicate 1 Prach only to DSP.
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= (1 << B_ACCESS_PRACH);
+ −
+ − // Select first UL data buffer.
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_ul_buffer_gprs[3] = 0;
+ −
+ − // Store CS type.
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_du_gprs[0][0] = cs_type;
+ −
+ − // Store UL data block.
+ − if(cs_type == CS_PAB8_TYPE)
+ − {
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_du_gprs[0][1] = ((API)(bsic << 2)) |
+ − ((API)(channel_request_data) << 8);
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_du_gprs[0][2] = 0;
+ − }
+ − else
+ − {
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_du_gprs[0][1] = ((API)(channel_request_data) << 5);
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_du_gprs[0][2] = ((API)(bsic << 10));
+ − }
+ −
+ − if (l1pa_l1ps_com.pra_info.prach_alloc == FIX_PRACH_ALLOC)
+ − {
+ − // Set fix alloc bit.
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_sched_mode_gprs |= (2 << B_MAC_MODE);
+ − }
+ − else
+ − {
+ − // Reset MAC mode to dynamic allocation
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_sched_mode_gprs &= ~(3 << B_MAC_MODE);
+ −
+ − #if !FF_L1_IT_DSP_USF
+ − #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)
+ − // Enable USF vote on timeslot 0
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_usf_vote_enable = 0x80;
+ − #endif
+ − #endif
+ − }
+ − }
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1pddsp_idle_prach_power() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − void l1pddsp_idle_prach_power(UWORD8 txpwr,
+ − UWORD16 radio_freq,
+ − UWORD8 ts)
+ − {
+ − #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3) || (RF_FAM == 61))
+ − UWORD16 pwr_data;
+ − #endif
+ −
+ − #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3) )
+ − // Force FIXED transmit power if requested.
+ − if(l1_config.tx_pwr_code == 0)
+ − {
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_power_gprs[ts] = l1_config.params.fixed_txpwr;
+ −
+ − // Control bitmap: update RAMP, use RAMP[5][..].
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[ts] =
+ − ((1 << B_RAMP_GPRS) | (5 << B_RAMP_NB_GPRS) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2));
+ −
+ − // Store Ramp.
+ − #if (CODE_VERSION != SIMULATION)
+ − Cust_get_ramp_tab(l1ps_dsp_com.pdsp_ndb_ptr->a_ramp_gprs[5],
+ − 0, /* not used */
+ − 0, /* not used */
+ − 1 /* arbitrary value for arfcn */ );
+ − #endif
+ − }
+ − else
+ − {
+ − // Get H/W value corresponding to txpwr command.
+ − pwr_data = Cust_get_pwr_data(txpwr, radio_freq
+ − #if(REL99 && FF_PRF)
+ − ,1
+ − #endif
+ − );
+ −
+ − // Store Transmit power.
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_power_gprs[ts] = ((pwr_data << 6) | 0x12);
+ −
+ − // Control bitmap: update RAMP, use RAMP[5][..].
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[ts] = ((1 << B_RAMP_GPRS) | (5 << B_RAMP_NB_GPRS) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2));
+ −
+ − // Store Ramp.
+ − #if (CODE_VERSION != SIMULATION)
+ − Cust_get_ramp_tab(&(l1ps_dsp_com.pdsp_ndb_ptr->a_ramp_gprs[5][0]), txpwr, txpwr, radio_freq);
+ − #endif
+ − }
+ − #endif
+ −
+ − #if (RF_FAM == 61)
+ − // Force FIXED transmit power if requested.
+ − if(l1_config.tx_pwr_code == 0)
+ − {
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_power_gprs[ts] = l1_config.params.fixed_txpwr;
+ −
+ − // Control bitmap: update RAMP, use RAMP[5][..].
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[ts] =
+ − ((1 << B_RAMP_GPRS) | (5 << B_RAMP_NB_GPRS) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2));
+ −
+ − // Store Ramp.
+ − #if (DSP ==38) || (DSP == 39)
+ − Cust_get_ramp_tab(l1ps_dsp_com.pdsp_ndb_ptr->a_drp_ramp2_gprs[5],
+ − 0, /* not used */
+ − 0, /* not used */
+ − 1 /* arbitrary value for arfcn */ );
+ − #endif
+ − }
+ − else
+ − {
+ − // Get H/W value corresponding to txpwr command.
+ − pwr_data = Cust_get_pwr_data(txpwr, radio_freq
+ − #if(REL99 && FF_PRF)
+ − ,1
+ − #endif
+ − );
+ −
+ − // Store Transmit power.
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_power_gprs[ts] = (API) (pwr_data);
+ −
+ − // Control bitmap: update RAMP, use RAMP[5][..].
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[ts] = ((1 << B_RAMP_GPRS) | (5 << B_RAMP_NB_GPRS) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2));
+ −
+ − // Store Ramp.
+ − #if(DSP == 38) || (DSP == 39)
+ − Cust_get_ramp_tab(&(l1ps_dsp_com.pdsp_ndb_ptr->a_drp_ramp2_gprs[5][0]), txpwr, txpwr, radio_freq);
+ − #endif
+ − }
+ − #endif //RF_FAM == 61
+ −
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1pddsp_single_block() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − void l1pddsp_single_tx_block(UWORD8 burst_nb,
+ − UWORD8 *data,
+ − UWORD8 tsc,
+ − UWORD16 radio_freq)
+ − {
+ − UWORD16 swap_bit; // 16 bit wide to allow shift left.
+ −
+ − // Burst number within a block.
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_burst_nb_gprs = burst_nb;
+ −
+ − // UL on TS=3.
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= 0x80 >> 3;
+ −
+ − // Swap I/Q management.
+ − swap_bit = l1ps_swap_iq_ul(radio_freq);
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= swap_bit << 15;
+ −
+ − // Select first UL polling buffer.
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_ul_buffer_gprs[3] = 8;
+ −
+ − // Store CS type: CS1 for Polling.
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[0][0] = CS1_TYPE_POLL;
+ −
+ − if(burst_nb == BURST_1)
+ − // Store UL data block.
+ − {
+ − API *ul_block_ptr = &(l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[0][2]);
+ − UWORD8 i,j;
+ −
+ − // Copy first 22 bytes in the first 11 words after header.
+ − for (i=0, j=0; j<11; j++)
+ − {
+ − ul_block_ptr[j] = ((API)(data[i])) | ((API)(data[i+1]) << 8);
+ − i += 2;
+ − }
+ − // Copy last UWORD8 (23rd) in the 12th word after header.
+ − ul_block_ptr[11] = data[22];
+ − }
+ −
+ − // Training sequence.
+ − // Rem: bcch_freq_ind is set within Hopping algo.
+ − l1s_dsp_com.dsp_db_w_ptr->d_ctrl_system |= tsc << B_TSQ;
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1pddsp_idle_rx_nb() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − #if FF_L1_IT_DSP_USF
+ − void l1pddsp_idle_rx_nb(UWORD8 burst_nb,
+ − UWORD8 tsc,
+ − UWORD16 radio_freq,
+ − UWORD8 timeslot_no,
+ − BOOL ptcch_dl,
+ − BOOL usf_interrupt)
+ − #else
+ − void l1pddsp_idle_rx_nb(UWORD8 burst_nb,
+ − UWORD8 tsc,
+ − UWORD16 radio_freq,
+ − UWORD8 timeslot_no,
+ − BOOL ptcch_dl)
+ − #endif
+ − {
+ − UWORD16 swap_bit; // 16 bit wide to allow shift left.
+ −
+ − // DL on TS=0.
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_d_gprs |= 0x80 >> timeslot_no;
+ −
+ − // Swap I/Q management.
+ − swap_bit = l1ps_swap_iq_dl(radio_freq);
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_d_gprs |= swap_bit << 15;
+ −
+ − if(ptcch_dl)
+ − {
+ − // PTCCH/DL case must be flagged to DSP.
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_d_gprs |= (1 << B_PTCCH_DL);
+ − }
+ −
+ − // Burst number within a block.
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_burst_nb_gprs = burst_nb;
+ −
+ − // Channel coding is forced to CS1.
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_ctrl_ched_gprs[timeslot_no] = CS1_TYPE_DATA;
+ −
+ − // pass information to DSP which good USF value is to be expected
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_usf_gprs[0] = (API) 0x07;
+ −
+ − #if FF_L1_IT_DSP_USF
+ − // In case of connection establishment mode with dynamic or fixed
+ − // allocation scheme we need to request the DSP USF interrupt for PRACH
+ − // scheduling. Latched by DSP during Work3
+ − if (burst_nb == 3)
+ − {
+ − if (usf_interrupt)
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_usf_vote_enable |= (1 << B_USF_IT);
+ − else
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_usf_vote_enable &= ~(1 << B_USF_IT);
+ − }
+ − #endif
+ −
+ − // RIF receiver algorithm: select 156.25.
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_sched_mode_gprs &= 0xFFFF ^ (1 << B_RIF_RX_MODE);
+ −
+ − // Training sequence.
+ − // Rem: bcch_freq_ind is set within Hopping algo.
+ − l1s_dsp_com.dsp_db_w_ptr->d_ctrl_system |= tsc << B_TSQ;
+ −
+ − }
+ −
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1pddsp_transfer_mslot_ctrl() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − void l1pddsp_transfer_mslot_ctrl(UWORD8 burst_nb,
+ − UWORD8 dl_bitmap,
+ − UWORD8 ul_bitmap,
+ − UWORD8 *usf_table,
+ − UWORD8 mac_mode,
+ − UWORD8 *ul_buffer_index,
+ − UWORD8 tsc,
+ − UWORD16 radio_freq,
+ − UWORD8 synchro_timeslot,
+ − #if FF_L1_IT_DSP_USF
+ − UWORD8 dsp_usf_interrupt
+ − #else
+ − UWORD8 usf_vote_enable
+ − #endif
+ − )
+ − {
+ − UWORD8 i;
+ − UWORD16 swap_bit; // 16 bit wide to allow shift left.
+ −
+ − // Burst number within a block.
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_burst_nb_gprs = burst_nb;
+ −
+ − // DL bitmap.
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_d_gprs = dl_bitmap;
+ −
+ − // UL bitmap.
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs = ul_bitmap;
+ −
+ − // Swap I/Q management for DL.
+ − swap_bit = l1ps_swap_iq_dl(radio_freq);
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_d_gprs |= swap_bit << 15;
+ −
+ − // Swap I/Q management for UL.
+ − swap_bit = l1ps_swap_iq_ul(radio_freq);
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= swap_bit << 15;
+ −
+ − if(burst_nb == 0)
+ − {
+ − // Store USF table
+ − for(i=0;i<(8 - synchro_timeslot);i++)
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_usf_gprs[i] = usf_table[i+synchro_timeslot];
+ −
+ − // Automatic CS detection.
+ − for(i=0;i<8;i++)
+ − {
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_ctrl_ched_gprs[i] = CS_AUTO_DETECT;
+ −
+ − // Select first UL polling buffer.
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_ul_buffer_gprs[i] = ul_buffer_index[i];
+ − }
+ −
+ − #if !FF_L1_IT_DSP_USF
+ − // USF vote enable programming
+ −
+ − #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)
+ − // Multislot TX allowed and usf_vote_enable suported: programs usf_vote_enable
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_usf_vote_enable = usf_vote_enable;
+ − #else
+ − // Single slot TX only and usf_vote_enable not supported
+ − // Modify MAC mode
+ − if (usf_vote_enable)
+ − // USF vote enabled --> Set MAC mode to dynamic mode
+ − mac_mode = DYN_ALLOC;
+ − else
+ − // USF vote disabled --> Set MAC mode to fixed mode
+ − mac_mode = FIX_ALLOC_NO_HALF;
+ − #endif
+ −
+ − #endif // !FF_L1_IT_DSP_USF
+ −
+ − // MAC mode.
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_sched_mode_gprs &= ~(3 << B_MAC_MODE);
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_sched_mode_gprs |= mac_mode << B_MAC_MODE;
+ − }
+ −
+ − #if FF_L1_IT_DSP_USF
+ − if(burst_nb == 3)
+ − {
+ − // Program DSP to generate an interrupt once USF available if
+ − // required. Latched by DSP during Work3.
+ − if (dsp_usf_interrupt)
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_usf_vote_enable = (1 << B_USF_IT);
+ − else
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_usf_vote_enable = 0;
+ − }
+ − #endif
+ −
+ − // RIF receiver algorithm: select 156.25.
+ − l1ps_dsp_com.pdsp_ndb_ptr->d_sched_mode_gprs &= 0xFFFF ^ (1 << B_RIF_RX_MODE);
+ −
+ − // d_fn
+ − // ----
+ − // bit [0..7] -> b_fn_report, unused for GPRS
+ − // bit [8..15] -> b_fn_sid , FN%104
+ − l1s_dsp_com.dsp_db_w_ptr->d_fn = ((l1s.next_time.fn_mod104)<<8);
+ −
+ − // Training sequence.
+ − // Rem: bcch_freq_ind is set within Hopping algo.
+ − l1s_dsp_com.dsp_db_w_ptr->d_ctrl_system |= tsc << B_TSQ;
+ −
+ − }
+ −
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1pddsp_transfer_mslot_power() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − void l1pddsp_transfer_mslot_power(UWORD8 *txpwr,
+ − UWORD16 radio_freq,
+ − UWORD8 ul_bitmap)
+ − {
+ − #define NO_TX 100
+ −
+ − UWORD16 i; // 16 bit needed for shifting pupose.
+ − UWORD8 last_TX = NO_TX;
+ − UWORD8 txpwr_ramp_up;
+ − UWORD8 txpwr_ramp_down;
+ − UWORD8 cpt_TX = 0;
+ − UWORD8 ts_mask;
+ −
+ − #if (REL99 && FF_PRF)
+ − UWORD8 number_uplink_timeslot = 0 ; // number of uplink timeslot for power reduction feature
+ − #endif
+ −
+ −
+ − #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3) || (RF_FAM == 61))
+ − UWORD16 pwr_data;
+ − UWORD16 d_ramp_idx;
+ − WORD16 ts_conv;
+ − #endif
+ −
+ − //Locosto #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
+ −
+ − // This function is called with an ul_bitmap which represents the abolute
+ − // position of any Tx bursts in this frame. This bitmap has already
+ − // absorbed any synchro change (in dl_tn), hence we need to do some
+ − // processing to recover the actual Tx timeslot number which is used
+ − // as an index into the txpwr array.
+ − //
+ − // Example : MS Class 8 with 4 Rx and 1 Tx :
+ − //
+ − //
+ − // dl_ts_alloc : 0x0f 0 0 0 0 R R R R
+ − // ul_ts_alloc : 0x02 0 0 0 0 0 0 T 0
+ − // shift + combine : 0 0 0 0 R R R R 0 T
+ − // set dl_tn=4 : R R R R 0 T 0 0
+ − // ul_bitmap : 0x04 0 0 0 0 0 1 0 0
+ − // i : 5
+ − //
+ − // Example : MS Class 8 with 1 Rx and 1 Tx on TS=7
+ − //
+ − // dl_ts_alloc : 0x01 0 0 0 0 0 0 0 R
+ − // ul_ts_alloc : 0x01 0 0 0 0 0 0 0 T
+ − // shift + combine : 0 0 0 0 0 0 0 R 0 0 T
+ − // set dl_tn=7 : R 0 0 T 0 0 0 0
+ − // ul_bitmap : 0x10 0 0 0 1 0 0 0 0
+ − // i : 3
+ − //
+ − // We recover the actual timeslot from the ul_bitmap by the following
+ − // method :
+ − //
+ − // ts = (i + dl_tn) - 3
+ − //
+ − // Where i is the loopindex usd to detect "1" in the ul_bitmap.
+ − // This works for MS class 8 because (3 <= i <= 5) if the
+ − // multislot class is respected.
+ −
+ − #if (REL99 && FF_PRF)// power reduction feature
+ − for (i=0; i<8; i++)
+ − {
+ − // computed number of uplink timeslot in order to determine uplink power reduction
+ − ts_mask = (0x80>>i);
+ − if (ul_bitmap & ts_mask)
+ − number_uplink_timeslot++;
+ − }
+ − #endif
+ −
+ −
+ − ts_conv = l1a_l1s_com.dl_tn - 3;
+ −
+ − // Index of the programmed ramps
+ − d_ramp_idx = 0;
+ −
+ − for(i=0;i<8;i++)
+ − {
+ − // Program Transmit power and ramp for allocated timeslots.
+ − if(ul_bitmap & (0x80>>i))
+ − {
+ − // Fixe transmit power.
+ − if(l1_config.tx_pwr_code == 0)
+ − {
+ − // Store Transmit power.
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_power_gprs[i] = l1_config.params.fixed_txpwr;
+ −
+ − // Control bitmap: update RAMP, use RAMP[d_ramp_idx][..].
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[i] =
+ − ((d_ramp_idx << B_RAMP_NB_GPRS) | (1 << B_RAMP_GPRS) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2));
+ −
+ − // Store Ramp.
+ − #if (RF_FAM == 61)
+ − #if (DSP ==38) || (DSP == 39)
+ − Cust_get_ramp_tab(l1ps_dsp_com.pdsp_ndb_ptr->a_drp_ramp2_gprs[d_ramp_idx++],
+ − 0, /* not used */
+ − 0, /* not used */
+ − 1 /* arbitrary value for arfcn */ );
+ − #endif
+ − #else
+ − #if (CODE_VERSION != SIMULATION)
+ − Cust_get_ramp_tab(l1ps_dsp_com.pdsp_ndb_ptr->a_ramp_gprs[d_ramp_idx++],
+ − 0, /* not used */
+ − 0, /* not used */
+ − 1 /* arbitrary value for arfcn */ );
+ − #endif
+ − #endif
+ − }
+ − else
+ − {
+ − // count the number of TX windows
+ − cpt_TX ++;
+ −
+ − // Get power amplifier data.
+ − #if(REL99 && FF_PRF)
+ − pwr_data = Cust_get_pwr_data(txpwr[i+ts_conv], radio_freq, number_uplink_timeslot);
+ − #else
+ − pwr_data = Cust_get_pwr_data(txpwr[i+ts_conv], radio_freq);
+ − #endif
+ −
+ −
+ − // Store Transmit power.
+ − #if(RF_FAM == 61)
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_power_gprs[i] = (pwr_data);
+ − #else
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_power_gprs[i] = ((pwr_data << 6) | 0x12);
+ − #endif
+ −
+ − // Control bitmap: update RAMP, use RAMP[d_ramp_idx][..] for slot i.
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[i] = ((d_ramp_idx << B_RAMP_NB_GPRS) | (1 << B_RAMP_GPRS) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2));
+ −
+ − // Store Ramp.
+ − // ==========
+ − // for the 1st TX the RAMP is: RAMP_UP_TX1 / RAMP_DOWN_TX1
+ − // for the 2nd TX the RAMP is: RAMP_UP_TX2 / RAMP_DOWN_TX1
+ − // for the 3rd TX the RAMP is: RAMP_UP_TX3 / RAMP_DOWN_TX2
+ − // (...)
+ − // for the (i)th TX the RAMP is: RAMP_UP_TX_(i) / RAMP_DOWN_TX_(i-1)
+ − // for the additionnal RAMP : xxxx / RAMP_DOWN_TX_last
+ −
+ − txpwr_ramp_up = txpwr[i+ts_conv]; // the ramp up is the current TX
+ −
+ − if(last_TX == NO_TX) // specific case of the first TX
+ − txpwr_ramp_down = txpwr[i+ts_conv]; // the ramp down is the current TX
+ − else
+ − txpwr_ramp_down = txpwr[last_TX+ts_conv]; // the ramp down is the previous TX
+ −
+ − #if(RF_FAM == 61)
+ − #if(DSP == 38) || (DSP == 39)
+ − Cust_get_ramp_tab(&(l1ps_dsp_com.pdsp_ndb_ptr->a_drp_ramp2_gprs[d_ramp_idx++][0]), txpwr_ramp_up, txpwr_ramp_down, radio_freq);
+ − #endif
+ − #else
+ − #if (CODE_VERSION != SIMULATION)
+ − Cust_get_ramp_tab(&(l1ps_dsp_com.pdsp_ndb_ptr->a_ramp_gprs[d_ramp_idx++][0]), txpwr_ramp_up, txpwr_ramp_down, radio_freq);
+ − #endif
+ − #endif
+ − }
+ −
+ − // memorize the last TX window
+ − last_TX = i;
+ − }
+ − else
+ − {
+ − // program an interrupt in the TS following
+ − // the last TX window and needed by the DSP
+ −
+ − // Is it the TS following a TX window ?
+ − #if 0 /* original LoCosto code */
+ − if((i == last_TX+1) && (i<8))
+ − #else /* FreeCalypso TCS211 reconstruction */
+ − if (i == last_TX+1)
+ − #endif
+ − {
+ − // program the interrupt
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[i] = (1 << B_MS_RULE);
+ − }
+ − }
+ − }
+ −
+ − // in a multi-TX case an additionnal ramp down must be set
+ − if(cpt_TX > 1)
+ − {
+ − // Control bitmap: update RAMP, use RAMP[d_ramp_idx][..] for slot i and set the interrupt
+ − #if 0 /* FreeCalypso TCS211 reconstruction */
+ − if((last_TX+1) <= 7)
+ − #endif
+ − l1ps_dsp_com.pdsp_db_w_ptr->a_ctrl_abb_gprs[last_TX+1] = ((d_ramp_idx << B_RAMP_NB_GPRS) | (1 << B_RAMP_GPRS) | (1 << B_MS_RULE));
+ −
+ − // Store Ramp.
+ − // ==========
+ − txpwr_ramp_up = txpwr[last_TX+ts_conv]; // this ramp up is unused (default: set to last_TX)
+ − txpwr_ramp_down = txpwr[last_TX+ts_conv]; // the ramp down is the last TX
+ −
+ − #if(RF_FAM == 61)
+ − #if(DSP ==38) || (DSP == 39)
+ − Cust_get_ramp_tab(&(l1ps_dsp_com.pdsp_ndb_ptr->a_drp_ramp2_gprs[d_ramp_idx][0]), txpwr_ramp_up, txpwr_ramp_down, radio_freq);
+ − #endif
+ − #else
+ − #if (CODE_VERSION != SIMULATION)
+ − Cust_get_ramp_tab(&(l1ps_dsp_com.pdsp_ndb_ptr->a_ramp_gprs[d_ramp_idx][0]), txpwr_ramp_up, txpwr_ramp_down, radio_freq);
+ − #endif
+ − #endif
+ − }
+ − // #endif Locosto
+ − }
+ −
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1pddsp_ul_ptcch_data() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − void l1pddsp_ul_ptcch_data(UWORD8 cs_type,
+ − UWORD16 channel_request_data,
+ − UWORD8 bsic,
+ − UWORD16 radio_freq,
+ − UWORD8 timeslot_no)
+ − {
+ − UWORD16 swap_bit; // 16 bit wide to allow shift left.
+ −
+ − // UL on TS=timeslot_no.
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= 0x80 >> timeslot_no;
+ −
+ − // Swap I/Q management.
+ − swap_bit = l1ps_swap_iq_ul(radio_freq);
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= swap_bit << 15;
+ −
+ − // Set "b_ptcch_ul" to indicate PTCCH/UL to DSP.
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_u_gprs |= (1 << B_PTCCH_UL);
+ −
+ − // Store CS type.
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_ptcchu_gprs[0] = cs_type;
+ −
+ − // Store UL data block.
+ − if(cs_type == CS_PAB8_TYPE)
+ − {
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_ptcchu_gprs[1] = ((API)(bsic << 2)) |
+ − ((API)(channel_request_data) << 8);
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_ptcchu_gprs[2] = 0;
+ − }
+ − else
+ − {
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_ptcchu_gprs[1] = ((API)(channel_request_data) << 5);
+ − l1ps_dsp_com.pdsp_ndb_ptr->a_ptcchu_gprs[2] = ((API)(bsic << 10));
+ − }
+ − }
+ −
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1pddsp_interf_meas_ctrl() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − void l1pddsp_interf_meas_ctrl(UWORD8 nb_meas_req)
+ − {
+ − // Interference measurement task set as a monitoring task within GSM interface.
+ − // 101 means 1 meas, 102 means 2 meas ...
+ − // Rem: swap I/Q is not managed for power measurements.
+ − l1s_dsp_com.dsp_db_w_ptr->d_task_md = INTERF_DSP_TASK + nb_meas_req;
+ − }
+ −
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1pddsp_transfer_meas_ctrl() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − void l1pddsp_transfer_meas_ctrl(UWORD8 meas_position)
+ − {
+ − // Store measurement position.
+ − // Rem: This is a L1S filtered information giving the position of the meas. as a
+ − // bitmap.
+ − // Rem: swap I/Q is not managed for power measurements.
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_pm_gprs = meas_position;
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1pddsp_meas_ctrl() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − void l1pddsp_meas_ctrl(UWORD8 nbmeas, UWORD8 pm_pos)
+ − {
+ − // Request Signal level measurement task to DSP. A bit map is passed
+ − // to DSP in order to specify the position of the measurement.
+ − // Note: MSB is TN = 0 and LSB is TN = 7.
+ − // Rem: swap I/Q is not managed for power measurements.
+ − // Note: currently a maximum of four Pm can be performed / TDMA. This would
+ − // be modified in a near futur.
+ − // Note: If a Rx is programmed i.e. pm_pos = 1, only a maximum
+ − // of 3 Pm is requested to DSP and position of the Pm are right shifted (Rx on TN = 0).
+ − // Remark: In packet Idle mode Rx are still on TN = 0. This implies three Pm
+ − // always after the Rx.
+ − l1ps_dsp_com.pdsp_db_w_ptr->d_task_pm_gprs = ((UWORD8) (0xff << (8 - nbmeas))) >> pm_pos;
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1pddsp_meas_read() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − void l1pddsp_meas_read(UWORD8 nbmeas, UWORD8 *a_pm)
+ − {
+ − UWORD8 i = 0;
+ − UWORD8 j;
+ − UWORD8 bit_mask = 0x80;
+ −
+ − // Looks for first PM position
+ − while ((i < 8) && (l1ps_dsp_com.pdsp_db_r_ptr->d_task_pm_gprs & bit_mask) == 0)
+ − {
+ − i++;
+ − bit_mask >>= 1;
+ − }
+ −
+ − // Read 'nbmeas' contiguous PM levels from the first PM position
+ − // Note: PM are always programmed on contiguous timeslots
+ − #if 0 /* original LoCosto code */
+ − for (j = 0; ((j < nbmeas)&&(i < 8)); j++)
+ − #else /* FreeCalypso TCS211 reconstruction */
+ − for (j = 0; j < nbmeas; j++)
+ − #endif
+ − {
+ − // Download PM from DSP/MCU memory interface
+ − a_pm[j] = (l1ps_dsp_com.pdsp_db_r_ptr->a_burst_pm_gprs[i] & 0xffff) >> 5;
+ −
+ − // Read next PM on following TN
+ − i++;
+ − }
+ − }
+ −
+ − /*-------------------------------------------------------*/
+ − /* l1pddsp_load_bcchn_task() */
+ − /*-------------------------------------------------------*/
+ − /* Parameters : */
+ − /* Return : */
+ − /* Functionality : */
+ − /*-------------------------------------------------------*/
+ − void l1pddsp_load_bcchn_task(UWORD8 tsq,UWORD16 radio_freq )
+ − {
+ − UWORD16 swap_bit = l1ps_swap_iq_dl(radio_freq);
+ −
+ − l1s_dsp_com.dsp_db_w_ptr->d_task_md = NBN_DSP_TASK | (swap_bit << 15); // Load BCCHN task
+ − l1s_dsp_com.dsp_db_w_ptr->d_ctrl_system |= tsq << B_TSQ;
+ − }
+ − #endif