changeset 245:bf5d58fc0de7

l1tm_cust.c: initial import from MV100 source
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 16 Jan 2017 01:37:37 +0000
parents e169f0018f40
children 03c8cdc20ffa
files chipsetsw/layer1/tm_cust0/l1tm_cust.c
diffstat 1 files changed, 2343 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/chipsetsw/layer1/tm_cust0/l1tm_cust.c	Sun Jan 15 18:13:30 2017 +0000
+++ b/chipsetsw/layer1/tm_cust0/l1tm_cust.c	Mon Jan 16 01:37:37 2017 +0000
@@ -1,1 +1,2343 @@
-/* dummy C source file */
+/************* Revision Controle System Header *************
+ *                  GSM Layer 1 software
+ * L1TM_CUST.C
+ *
+ *        Filename %M%
+ *        Version  %I%
+ *        Date     %G%
+ * 
+ ************* Revision Controle System Header *************/
+
+#include "l1_confg.h"
+#if TESTMODE
+
+#include "tm_defs.h"
+#include "l1_const.h"
+#include "l1_types.h"
+
+#include "l1tm_defty.h"
+#include "l1tm_cust.h"
+
+#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
+#include "l1_defty.h"
+#include "l1_msgty.h"
+#include "l1_tabs.h"
+
+#include "l1tm_msgty.h"
+#include "l1tm_varex.h"
+
+#include "abb.h"
+
+#if (RF==35)
+  #include "tpudrv35.h"
+  #include "l1_rf35.h"
+#endif
+
+#if (RF==12)
+  #include "tpudrv12.h"
+  #include "l1_rf12.h"
+#endif
+
+#if (RF==10)
+  #include "tpudrv10.h"
+  #include "l1_rf10.h"
+#endif
+
+#if (RF==8)
+  #include "tpudrv8.h"
+  #include "l1_rf8.h"
+#endif
+
+#if (RF==2)
+  #include "l1_rf2.h"
+#endif
+
+#include <string.h>
+
+#include "rvf_api.h"
+#include "Rtc_api.h"
+
+API voice_a_fir31_downlink[31]={0x4000,
+	0x0000,0x0000,0x0000,0x0000,0x0000,
+	0x0000,0x0000,0x0000,0x0000,0x0000,
+	0x0000,0x0000,0x0000,0x0000,0x0000,
+	0x0000,0x0000,0x0000,0x0000,0x0000,
+	0x0000,0x0000,0x0000,0x0000,0x0000,
+	0x0000,0x0000,0x0000,0x0000,0x0000};
+
+API melody_a_fir31_downlink_shipping[31]={0x01BC,
+	0xFF96, 0x0271, 0xFEFB, 0xFEB5, 0xFD9D,
+	0x054B, 0x00CF, 0xFF48, 0xF6A1, 0x0357,
+	0x0761, 0x0C20, 0xEE2D, 0xD721, 0x7620,
+	0xD721, 0xEE2D, 0x0C20, 0x0761, 0x0357, 
+	0xF6A1, 0xFF48, 0x00CF, 0x054B, 0xFD9D, 
+	0xFEB5, 0xFEFB, 0x0271, 0xFF96, 0x01BC};
+
+API melody_a_fir31_downlink_4000[31]={0x4000, 
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+	0x0000};
+
+
+// Import band configuration from Flash module (need to replace by an access function)
+//extern UWORD8       std;
+extern T_L1_CONFIG  l1_config;
+extern T_RF rf;
+extern T_RF_BAND rf_band[GSM_BANDS];
+extern UWORD16 AGC_TABLE[AGC_TABLE_SIZE];
+extern T_ADC adc;
+extern T_ADCCAL adc_cal;
+extern UWORD16 TM_ul_data[16]; //Uplink data to be stored into ABB Uplink buffer
+extern T_STD_CONFIG std_config[];
+static UWORD8 tm_band = 0;
+
+//glowing,2004-06-17,import from M188
+extern unsigned char g_pcsyncstatus;
+const char * CmdPW = "123456";// must be 1-16 byte,when user use the stw 60 password,we check it,if it is equal with this element, set OpenCmd=1
+unsigned char OpenCmd=0;//when it is 1,we can use those write phone command
+//glowing,2004-06-17,end of import
+
+// External function prototypes
+void get_cal_from_nvmem (UWORD8 *ptr, UWORD16 len, UWORD8 id);
+UWORD8 save_cal_in_nvmem (UWORD8 *ptr, UWORD16 len, UWORD8 id);
+void Cust_init_std(void);
+void l1_tpu_init_light(void);
+
+enum {
+  TM_RF_ID        = 0,
+  TM_ADC_ID       = 1
+};
+
+typedef signed char effs_t;
+// external FFS function prototypes
+effs_t ffs_mkdir(const char *pathname);
+void config_ffs_write(char type);
+									   
+/***********************************************************************/
+/*                           TESTMODE 4.X                              */
+/***********************************************************************/
+
+
+/*----------------------------------------------------------*/
+/* Cust_tm_init()                                           */
+/*----------------------------------------------------------*/
+/* Parameters :                                             */
+/* Return     :                                             */
+/* Functionality : Init default configuration for TM params */
+/*----------------------------------------------------------*/
+
+void Cust_tm_init(void)
+{
+  UWORD32 i;
+
+  l1_config.adc_enable                             = ADC_ENABLE; // ADC readings enabled
+  l1_config.agc_enable                             = AGC_ENABLE; // AGC algo enabled
+  l1_config.afc_enable                             = AFC_ENABLE; // AFC algo enabled
+  l1_config.tmode.rf_params.bcch_arfcn             = TM_BCCH_ARFCN;
+  l1_config.tmode.rf_params.tch_arfcn              = TM_TCH_ARFCN;
+  l1_config.tmode.rf_params.mon_arfcn              = TM_MON_ARFCN;
+  l1_config.tmode.rf_params.channel_type           = TM_CHAN_TYPE; // TCH_F
+  l1_config.tmode.rf_params.subchannel             = TM_SUB_CHAN;
+  l1_config.tmode.rf_params.reload_ramps_flag      = 0;
+  l1_config.tmode.rf_params.tmode_continuous       = TM_NO_CONTINUOUS;
+  l1_config.tmode.rx_params.slot_num               = TM_SLOT_NUM; // Time Slot
+  l1_config.tmode.rx_params.agc                    = TM_AGC_VALUE; //This may be outside the range of the RF chip used
+  l1_config.tmode.rx_params.pm_enable              = TM_PM_ENABLE;
+  l1_config.tmode.rx_params.lna_off                = TM_LNA_OFF;
+  l1_config.tmode.rx_params.number_of_measurements = TM_NUM_MEAS;  
+  l1_config.tmode.rx_params.place_of_measurement   = TM_WIN_MEAS;
+  l1_config.tmode.tx_params.txpwr                  = TM_TXPWR; // Min power level for GSM900
+  l1_config.tmode.tx_params.txpwr_skip             = TM_TXPWR_SKIP;
+  l1_config.tmode.tx_params.timing_advance         = TM_TA;
+  l1_config.tmode.tx_params.burst_type             = TM_BURST_TYPE; // default is normal up-link burst
+  l1_config.tmode.tx_params.burst_data             = TM_BURST_DATA; // default is all zeros
+  l1_config.tmode.tx_params.tsc                    = TM_TSC; // Training Sequence ("BCC" on BSS)
+  #if (CODE_VERSION != SIMULATION)
+    l1_config.tmode.stats_config.num_loops         = TM_NUM_LOOPS; // 0 actually means infinite
+  #else
+    l1_config.tmode.stats_config.num_loops         = 4; // 0 actually means infinite
+  #endif
+  l1_config.tmode.stats_config.auto_result_loops   = TM_AUTO_RESULT_LOOPS; // 0 actually means infinite
+  l1_config.tmode.stats_config.auto_reset_loops    = TM_AUTO_RESET_LOOPS; // 0 actually means infinite
+  l1_config.tmode.stats_config.stat_type           = TM_STAT_TYPE;
+  l1_config.tmode.stats_config.stat_bitmask        = TM_STAT_BITMASK;
+
+  #if (CODE_VERSION != SIMULATION)
+    // Initialize APCDEL1 register of Omega
+    ABB_Write_Register_on_page(PAGE0, APCDEL1, (C_APCDEL - 0x0004) >> 6);
+  #endif
+
+  l1tm.tm_msg_received                       = FALSE;
+
+  for (i=0;i<16;i++)
+    TM_ul_data[i]=0;
+
+  #if L1_GPRS
+    l1_config.tmode.rf_params.pdtch_arfcn          = TM_PDTCH_ARFCN;
+    l1_config.tmode.rf_params.multislot_class      = TM_MULTISLOT_CLASS;
+    l1_config.tmode.stats_config.stat_gprs_slots   = TM_STAT_GPRS_SLOTS;
+    l1_config.tmode.rx_params.timeslot_alloc       = TM_RX_ALLOCATION;
+    l1_config.tmode.rx_params.coding_scheme        = TM_RX_CODING_SCHEME;
+    l1_config.tmode.tx_params.timeslot_alloc       = TM_TX_ALLOCATION;
+    l1_config.tmode.tx_params.coding_scheme        = TM_TX_CODING_SCHEME;
+    for (i=0; i<8; i++)
+      l1_config.tmode.tx_params.txpwr_gprs[i]      = TM_TXPWR_GPRS;
+
+    for (i=0; i<27; i++)
+      l1_config.tmode.tx_params.rlc_buffer[i] = 0;
+  #endif
+}
+
+
+/**********************************************************************/
+/* Test mode functions used for RF calibration                        */
+/**********************************************************************/
+
+void Cust_tm_rf_param_write(T_TM_RETURN *tm_return, WORD16 index, UWORD16 value)
+{
+  switch (index)
+  {
+    case STD_BAND_FLAG:
+    {
+      UWORD8 std_temp, band_temp;
+
+      std_temp  = value & 0xff;  // tm_band = b7..0 of value
+      band_temp = value >> 8;    // band    = b15..8 of value
+          // get define 
+      //if (sizeof(std_config)/sizeof(T_STD_CONFIG) <= std_temp)
+      if (9 <= std_temp)  // std max
+      {
+        tm_return->status = E_BADINDEX;
+        break;
+      }
+      else if ( GSM_BANDS <= band_temp)
+      {
+        tm_return->status = E_BADINDEX;
+        break;
+      }
+      else if ( BAND_NONE == std_config[std_temp].band[band_temp])
+      {
+        tm_return->status = E_BADINDEX;
+        break;
+      } 
+      else
+      {
+        l1_config.std.id = std_temp;  
+        tm_band = band_temp; 
+        // update RAM struct with either default or ffs
+        Cust_init_std();
+        l1_tpu_init_light();
+        tm_return->status = E_OK;
+        break;
+      }
+    }
+    
+    case INITIAL_AFC_DAC:
+    {
+      rf.afc.eeprom_afc = (WORD16) value << 3; // shift to put into F13.3 format
+      l1_config.params.eeprom_afc = rf.afc.eeprom_afc;
+
+      tm_return->status = E_OK;
+      break;
+    }
+    default:
+    {
+      tm_return->status = E_BADINDEX;
+      break;
+    }
+  } // end switch
+}
+
+void Cust_tm_rf_param_read(T_TM_RETURN *tm_return, WORD16 index)
+{
+  volatile UWORD16 value;
+
+  switch (index)
+  {
+    case STD_BAND_FLAG:
+    {
+       value = ((tm_band << 8) | (l1_config.std.id) ); // return global std, tm_band (intel format)
+      break;
+    }
+    case INITIAL_AFC_DAC:
+    {
+      value = rf.afc.eeprom_afc >> 3; // returned as F13.3
+      break;
+    }
+    default:
+    {
+      tm_return->size = 0;
+      tm_return->status = E_BADINDEX;
+      return;
+    }
+  } // end switch
+
+  memcpy(tm_return->result, (UWORD8 *)&value, 2);
+  tm_return->size = 2;
+  tm_return->status = E_OK;
+}
+
+void Cust_tm_rf_table_write(T_TM_RETURN *tm_return, WORD8 index, UWORD8 size, UWORD8 table[])
+{
+  UWORD8 band=0;
+
+  tm_return->index = index;  // store index before it gets modified
+  tm_return->size = 0;
+
+  switch (index)
+  {
+    case RX_AGC_TABLE:
+    {
+      if (size != sizeof(AGC_TABLE))
+      {
+        tm_return->status = E_BADSIZE;
+        break;
+      }
+
+      memcpy(&AGC_TABLE[0], table, size);
+      tm_return->status = E_OK;
+      break;
+    }
+    case AFC_PARAMS:
+    {
+
+      #if (VCXO_ALGO == 1)
+        if (size != 24)  //  4 UWORD32 + 4 WORD16 values
+      #else
+        if (size != 16)  // 4 UWORD32 values
+      #endif
+      {
+        tm_return->status = E_BADSIZE;
+        break;
+      }
+
+      memcpy(&rf.afc.psi_sta_inv, table, size);
+      l1_config.params.psi_sta_inv  = rf.afc.psi_sta_inv;
+      l1_config.params.psi_st       = rf.afc.psi_st;
+      l1_config.params.psi_st_32    = rf.afc.psi_st_32;
+      l1_config.params.psi_st_inv   = rf.afc.psi_st_inv;
+
+   #if (CODE_VERSION == NOT_SIMULATION)
+      #if (VCXO_ALGO == 1)
+        l1_config.params.afc_dac_center = rf.afc.dac_center;
+        l1_config.params.afc_dac_min    = rf.afc.dac_min;   
+        l1_config.params.afc_dac_max    = rf.afc.dac_max;   
+        l1_config.params.afc_snr_thr    = rf.afc.snr_thr;   
+      #endif
+      #endif
+
+      tm_return->status = E_OK;
+      break;
+    }
+    case RX_AGC_GLOBAL_PARAMS:
+    {
+      if (size != 10)  // 5 UWORD16 values
+      {
+        tm_return->status = E_BADSIZE;
+        break;
+      }
+
+      memcpy(&rf.rx.agc.low_agc_noise_thr, table, size);
+      l1_config.params.low_agc_noise_thr  = rf.rx.agc.low_agc_noise_thr;
+      l1_config.params.high_agc_sat_thr   = rf.rx.agc.high_agc_sat_thr;
+      l1_config.params.low_agc            = rf.rx.agc.low_agc;
+      l1_config.params.high_agc           = rf.rx.agc.high_agc;
+
+      tm_return->status = E_OK;
+      break;
+    }
+    case RX_IL_2_AGC_MAX:
+    {
+      if (size != sizeof(rf.rx.agc.il2agc_max))
+      {
+        tm_return->status = E_BADSIZE;
+        break;
+      }
+
+      memcpy(&rf.rx.agc.il2agc_max[0], table, size);
+      tm_return->status = E_OK;
+      break;
+    }
+    case RX_IL_2_AGC_PWR:
+    {
+      if (size != sizeof(rf.rx.agc.il2agc_pwr))
+      {
+        tm_return->status = E_BADSIZE;
+        break;
+      }
+
+      memcpy(&rf.rx.agc.il2agc_pwr[0], table, size);
+      tm_return->status = E_OK;
+      break;
+    }
+    case RX_IL_2_AGC_AV:
+    {
+      if (size != sizeof(rf.rx.agc.il2agc_av))
+      {
+        tm_return->status = E_BADSIZE;
+        break;
+      }
+
+      memcpy(&rf.rx.agc.il2agc_av[0], table, size);
+      tm_return->status = E_OK;
+      break;
+    }
+    case TX_LEVELS:
+    {
+      if (size != sizeof(rf_band[tm_band].tx.levels))
+      {
+        tm_return->status = E_BADSIZE;
+        break;
+      }
+
+      memcpy(&rf_band[tm_band].tx.levels[0], table, size);
+      tm_return->status = E_OK;
+      break;
+    }
+    case TX_CAL_CHAN: // generic for all bands
+    {
+      if (size != sizeof(rf_band[tm_band].tx.chan_cal_table))
+      {
+        tm_return->status = E_BADSIZE;
+        break;
+      }
+      
+      memcpy(&rf_band[tm_band].tx.chan_cal_table[0][0], table, size);
+      tm_return->status = E_OK;
+      break;
+    }
+    case TX_CAL_TEMP: // generic for all bands
+    {
+      if (size != sizeof(rf_band[tm_band].tx.temp))
+      {
+        tm_return->status = E_BADSIZE;
+        break;
+      }
+
+      memcpy(&rf_band[tm_band].tx.temp[0], table, size);
+      tm_return->status = E_OK;
+      break;
+    }
+    case RX_CAL_CHAN:  // generic for all bands
+    {
+      if (size != sizeof(rf_band[tm_band].rx.agc_bands))
+      {
+        tm_return->status = E_BADSIZE;
+        break;
+      }
+
+      memcpy(&rf_band[tm_band].rx.agc_bands[0], table, size);
+      tm_return->status = E_OK;
+      break;
+    }
+    case RX_CAL_TEMP:  // generic for all bands
+    {
+      if (size != sizeof(rf_band[tm_band].rx.temp))
+      {
+        tm_return->status = E_BADSIZE;
+        break;
+      }
+
+      memcpy(&rf_band[tm_band].rx.temp[0], table, size);
+      tm_return->status = E_OK;
+      break;
+    }
+    case RX_AGC_PARAMS:
+    {
+      if (size != sizeof(rf_band[tm_band].rx.rx_cal_params))
+      {
+        tm_return->status = E_BADSIZE;
+        break;
+      }
+
+      memcpy(&rf_band[tm_band].rx.rx_cal_params, table, size);
+      if (tm_band == 0)
+      {
+          l1_config.std.g_magic_band1             = rf_band[tm_band].rx.rx_cal_params.g_magic;
+          l1_config.std.lna_att_band1             = rf_band[tm_band].rx.rx_cal_params.lna_att;
+          l1_config.std.lna_switch_thr_low_band1  = rf_band[tm_band].rx.rx_cal_params.lna_switch_thr_low;
+          l1_config.std.lna_switch_thr_high_band1 = rf_band[tm_band].rx.rx_cal_params.lna_switch_thr_high;
+        }
+      else if (tm_band == 1)
+        {
+          l1_config.std.g_magic_band2             = rf_band[tm_band].rx.rx_cal_params.g_magic;
+          l1_config.std.lna_att_band2             = rf_band[tm_band].rx.rx_cal_params.lna_att;
+          l1_config.std.lna_switch_thr_low_band2  = rf_band[tm_band].rx.rx_cal_params.lna_switch_thr_low;
+          l1_config.std.lna_switch_thr_high_band2 = rf_band[tm_band].rx.rx_cal_params.lna_switch_thr_high;
+        }
+        else
+        {
+          tm_return->status = E_INVAL;
+          break;
+        }
+
+      tm_return->status = E_OK;
+      break;
+    }
+    case TX_CAL_EXTREME:
+    case RX_CAL_LEVEL:
+    {
+      tm_return->status = E_NOSUBSYS;
+      break;
+    }
+    #if L1_GPRS
+      case RLC_TX_BUFFER_CS1:
+      case RLC_TX_BUFFER_CS2:
+      case RLC_TX_BUFFER_CS3:
+      case RLC_TX_BUFFER_CS4:
+      {
+        UWORD8 i, buffer_size;
+
+        tm_return->index = index;  // store index before it gets modified
+        tm_return->size  = 0;
+
+        buffer_size = size/2 + size%2;  // bytes will be concatenated into UWORD16
+
+        if (buffer_size > 27)  //max. number of data bytes
+        {
+          tm_return->status = E_BADSIZE;
+          break;
+        }
+
+        // make sure that last byte is zero in case of odd number of bytes
+        table[size] = 0; 
+ 
+        // init the whole buffer before downloading new data
+        for (i=0; i<27; i++)
+          l1_config.tmode.tx_params.rlc_buffer[i] = 0;
+
+        for (i=0; i<buffer_size; i++)
+        {
+          l1_config.tmode.tx_params.rlc_buffer[i] = (table[2*i+1] << 8) | table[2*i];
+        }
+        l1_config.tmode.tx_params.rlc_buffer_size = buffer_size;
+
+        tm_return->status = E_OK;
+        break;
+      }
+    #endif
+    case TX_DATA_BUFFER:
+    {
+      UWORD8 i;
+
+      tm_return->index = index;  // store index before it gets modified
+      tm_return->size  = 0;
+
+      if (size != 32)  // 16 UWORD16 (containing 10 data bits each)
+      {
+        tm_return->status = E_BADSIZE;
+        break;
+      }
+
+      memcpy(&TM_ul_data, table, size);
+
+      for (i=0; i<16; i++)
+      {
+        TM_ul_data[i] = TM_ul_data[i] << 6;
+      }        	    
+
+      tm_return->status = E_OK;
+      break;
+    }  
+    default:
+    {
+      tm_return->status = E_BADINDEX;
+      break;
+    }
+  } // end switch
+}
+
+void Cust_tm_rf_table_read(T_TM_RETURN *tm_return, WORD8 index)
+{
+  switch (index)
+  {
+    case RX_AGC_TABLE:
+    {
+      tm_return->size = sizeof(AGC_TABLE);
+      memcpy(tm_return->result, &AGC_TABLE[0], tm_return->size);
+      break;
+    }
+    case AFC_PARAMS:
+    {
+      #if (VCXO_ALGO == 1)
+      tm_return->size = 24;  // 4 UWORD32's + 4 WORD16
+      #else
+      tm_return->size = 16;  // 4 UWORD32's
+      #endif
+      memcpy(tm_return->result, &rf.afc.psi_sta_inv, tm_return->size);
+      break;
+    }
+    case RX_AGC_GLOBAL_PARAMS:
+    {
+
+      tm_return->size = 10;  // 5 UWORD16's
+      memcpy(tm_return->result, &rf.rx.agc.low_agc_noise_thr, tm_return->size);
+
+      break;
+    }
+    case RX_IL_2_AGC_MAX:
+    {
+      tm_return->size = sizeof(rf.rx.agc.il2agc_max);
+      memcpy(tm_return->result, &rf.rx.agc.il2agc_max[0], tm_return->size);
+      break;
+    }
+    case RX_IL_2_AGC_PWR:
+    {
+      tm_return->size = sizeof(rf.rx.agc.il2agc_pwr);
+      memcpy(tm_return->result, &rf.rx.agc.il2agc_pwr[0], tm_return->size);
+      break;
+    }
+    case RX_IL_2_AGC_AV:
+    {
+      tm_return->size = sizeof(rf.rx.agc.il2agc_av);
+      memcpy(tm_return->result, &rf.rx.agc.il2agc_av[0], tm_return->size);
+      break;
+    }
+    case TX_LEVELS:
+    {
+      tm_return->size = sizeof(rf_band[tm_band].tx.levels);
+      memcpy(tm_return->result, &rf_band[tm_band].tx.levels[0], tm_return->size);
+      break;
+    }
+    case TX_CAL_CHAN: // generic for all bands
+    {
+      tm_return->size = sizeof(rf_band[tm_band].tx.chan_cal_table);
+      memcpy(tm_return->result, &rf_band[tm_band].tx.chan_cal_table[0][0], tm_return->size);
+      break;
+    }
+    case TX_CAL_TEMP:  // generic for all bands
+    {
+      tm_return->size = sizeof(rf_band[tm_band].tx.temp);
+      memcpy(tm_return->result, &rf_band[tm_band].tx.temp[0], tm_return->size);
+      break;
+    }
+    case RX_CAL_CHAN:  // generic for all bands
+    {
+      tm_return->size = sizeof(rf_band[tm_band].rx.agc_bands);
+      memcpy(tm_return->result, &rf_band[tm_band].rx.agc_bands[0], tm_return->size);
+      break;
+    }
+    case RX_CAL_TEMP:  // generic for all bands
+    {
+      tm_return->size = sizeof(rf_band[tm_band].rx.temp);
+      memcpy(tm_return->result, &rf_band[tm_band].rx.temp[0], tm_return->size);
+      break;
+    }
+    case RX_AGC_PARAMS:
+    {
+      // WARNING: sizeof(rf.rx.rx_cal_params[band]) returns 12 because of alignment
+      tm_return->size = 10;  // five UWORD16's
+      memcpy(tm_return->result, &rf_band[tm_band].rx.rx_cal_params, tm_return->size);
+      break;
+    }
+    case TX_CAL_EXTREME:
+    case RX_CAL_LEVEL:
+    {
+      tm_return->size = 0;
+      tm_return->status = E_NOSUBSYS;
+      return;
+    }
+    #if L1_GPRS
+      case RLC_TX_BUFFER_CS1:
+      case RLC_TX_BUFFER_CS2:
+      case RLC_TX_BUFFER_CS3:
+      case RLC_TX_BUFFER_CS4:
+      {
+        tm_return->size = l1_config.tmode.tx_params.rlc_buffer_size * 2; // UWORD16's
+        memcpy(tm_return->result, &l1_config.tmode.tx_params.rlc_buffer[0], tm_return->size);
+		break;
+      }
+
+    #endif
+    case TX_DATA_BUFFER:
+    {
+      tm_return->size = 32; //16*UWORD16
+      memcpy(tm_return->result, &TM_ul_data[0], tm_return->size);
+      break;
+
+    }
+    #if (RF==35)
+    case RX_PLL_TUNING_TABLE:
+    {
+      tm_return->size = sizeof(pll_tuning); //6*UWORD16
+      memcpy(tm_return->result, &pll_tuning, tm_return->size);
+
+      pll_tuning.enable    = 0;
+
+      break;
+    }
+    #endif
+    default:
+    {
+      tm_return->size = 0;
+      tm_return->status = E_BADINDEX;
+      return;
+    }
+  }  // end switch
+
+  tm_return->index  = index;
+  tm_return->status = E_OK;
+}
+
+void Cust_tm_rx_param_write(T_TM_RETURN *tm_return, WORD16 index, UWORD16 value)
+{
+  switch (index)
+  {
+    case RX_FRONT_DELAY:
+    {
+      //delay for dual band not implemented yet
+      rf.tx.prg_tx = value;
+      l1_config.params.prg_tx_gsm = rf.tx.prg_tx;
+      l1_config.params.prg_tx_dcs = rf.tx.prg_tx;
+
+      tm_return->status = E_OK;
+      break;
+    }
+    default:
+    {
+      tm_return->status = E_BADINDEX;
+      break;
+    }
+  } // end switch
+}
+
+void Cust_tm_rx_param_read(T_TM_RETURN *tm_return, WORD16 index)
+{
+  volatile UWORD16 value;
+
+  switch (index)
+  {
+    case RX_FRONT_DELAY:
+    {
+      value = rf.tx.prg_tx;
+      break;
+    }
+    default:
+    {
+      tm_return->status = E_BADINDEX;
+      tm_return->size = 0;
+      return;
+    }
+  } // end switch
+
+  memcpy(tm_return->result, (UWORD8 *)&value, 2);
+  tm_return->size = 2;
+  tm_return->status = E_OK;
+}
+
+void Cust_tm_tx_param_write(T_TM_RETURN *tm_return, WORD16 index, UWORD16 value, UWORD8 band)
+{
+  switch (index)
+  {
+    case TX_APC_DAC:
+    {
+      // generic for all bands
+      rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].apc = value;
+
+      tm_return->status = E_OK;
+      break;
+    }
+    case TX_RAMP_TEMPLATE:
+    {
+      if (value >= sizeof(rf_band[tm_band].tx.ramp_tables)/sizeof(rf_band[tm_band].tx.ramp_tables[0]))  // [0..15]
+      {
+        tm_return->status = E_INVAL;
+        break;
+      }
+
+      // generic for all bands
+        rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].ramp_index = value;
+
+      tm_return->status = E_OK;
+      l1_config.tmode.rf_params.reload_ramps_flag = 1;
+      break;
+    }
+    case TX_CHAN_CAL_TABLE:
+    {
+      if (value >= sizeof(rf_band[tm_band].tx.chan_cal_table)/sizeof(rf_band[tm_band].tx.chan_cal_table[0]))
+      {
+        tm_return->status = E_INVAL;
+        break;
+      }
+
+      // generic for all bands
+      rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].chan_cal_index = value;
+
+        tm_return->status = E_OK;
+      
+      break;
+      }
+    case TX_BURST_TYPE:
+      {
+      if (value > 1)  // [0..1]
+      {
+        tm_return->status = E_INVAL;
+        break;
+      }
+      l1_config.tmode.tx_params.burst_type = value;
+      tm_return->status = E_OK;
+      break;
+    }
+    case TX_BURST_DATA:
+    {
+      // range is [0..10], but we only support [0..2] and [5..13] at the moment
+      if ((value > 2 && value < 5) || (value > 13))
+      {
+        tm_return->status = E_INVAL;
+        break;
+      }
+      l1_config.tmode.tx_params.burst_data = value;
+      tm_return->status = E_OK;
+      break;
+    }
+    case TX_TRAINING_SEQ:
+    {
+      if (value > 7)  // [0..7]
+      {
+        tm_return->status = E_INVAL;
+        break;
+      }
+      l1_config.tmode.tx_params.tsc = value;
+      tm_return->status = E_OK;
+      break;
+    }
+    default:
+    {
+      tm_return->status = E_BADINDEX;
+      break;
+    }
+  } // end switch
+}
+
+void Cust_tm_tx_param_read(T_TM_RETURN *tm_return, WORD16 index, UWORD8 band)
+{
+  volatile UWORD16 value;
+
+  switch (index)
+  {
+    case TX_PWR_LEVEL:
+    {
+      value = l1_config.tmode.tx_params.txpwr;
+      break;
+    }
+    case TX_APC_DAC:
+    {
+      value = rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].apc;
+      break;
+    }
+    case TX_RAMP_TEMPLATE:
+    {
+      value = rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].ramp_index;
+      break;
+    }
+    case TX_CHAN_CAL_TABLE:
+    {
+      value = rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].chan_cal_index;
+      break;
+    }
+    case TX_BURST_TYPE:
+    {
+      value = l1_config.tmode.tx_params.burst_type;
+      break;
+    }
+    case TX_BURST_DATA:
+    {
+      value = l1_config.tmode.tx_params.burst_data;
+      break;
+    }
+    case TX_TIMING_ADVANCE:
+    {
+      value = l1_config.tmode.tx_params.timing_advance;
+      break;
+    }
+    case TX_TRAINING_SEQ:
+    {
+      value = l1_config.tmode.tx_params.tsc;
+      break;
+    }
+    case TX_PWR_SKIP:
+    {
+     value = l1_config.tmode.tx_params.txpwr_skip;
+     break;
+    }
+    #if L1_GPRS
+      case TX_GPRS_POWER0:
+      case TX_GPRS_POWER1:
+      case TX_GPRS_POWER2:
+      case TX_GPRS_POWER3:
+      case TX_GPRS_POWER4:
+      case TX_GPRS_POWER5:
+      case TX_GPRS_POWER6:
+      case TX_GPRS_POWER7:
+      {
+        value = l1_config.tmode.tx_params.txpwr_gprs[index - TX_GPRS_POWER0];
+        break;
+      }
+      case TX_GPRS_SLOTS:
+      {
+        value = l1_config.tmode.tx_params.timeslot_alloc;
+        break;
+      }
+      case TX_GPRS_CODING:
+      {
+        value = l1_config.tmode.tx_params.coding_scheme;
+        break;
+      }
+    #endif
+    default:
+    {
+      tm_return->status = E_BADINDEX;
+      tm_return->size = 0;
+      return;
+    }
+  } // end switch
+
+  memcpy(tm_return->result, (UWORD8 *)&value, 2);
+  tm_return->size = 2;
+  tm_return->status = E_OK;
+}
+
+void Cust_tm_tx_template_write(T_TM_RETURN *tm_return, WORD8 index, UWORD8 size, UWORD8 table[])
+{
+  if (index >= sizeof(rf_band[tm_band].tx.ramp_tables)/sizeof(T_TX_RAMP))
+  {
+    tm_return->status = E_BADINDEX;
+  }
+  else if (size != sizeof(T_TX_RAMP))
+  {
+    // We are writing both the up and down ramps; size must be exact.
+    tm_return->status = E_BADSIZE;
+  }
+  else
+  {
+    memcpy(rf_band[tm_band].tx.ramp_tables[index].ramp_up, &table[0], size/2);
+    memcpy(rf_band[tm_band].tx.ramp_tables[index].ramp_down, &table[size/2], size/2);
+    tm_return->status = E_OK;
+    l1_config.tmode.rf_params.reload_ramps_flag = 1;
+  }
+
+  tm_return->index = index;
+  tm_return->size = 0;
+}
+
+void Cust_tm_tx_template_read(T_TM_RETURN *tm_return, WORD8 index)
+{
+  tm_return->index = index;
+
+  if (index >= sizeof(rf_band[tm_band].tx.ramp_tables)/sizeof(T_TX_RAMP))
+  {
+    tm_return->status = E_BADINDEX;
+    tm_return->size = 0;
+    return;
+  }
+   
+  memcpy(&tm_return->result[0], rf_band[tm_band].tx.ramp_tables[index].ramp_up, sizeof(rf_band[tm_band].tx.ramp_tables[index].ramp_up));
+  memcpy(&tm_return->result[sizeof(rf_band[tm_band].tx.ramp_tables[index].ramp_up)], rf_band[tm_band].tx.ramp_tables[index].ramp_down, sizeof(rf_band[tm_band].tx.ramp_tables[index].ramp_down));
+  tm_return->size = sizeof(rf_band[tm_band].tx.ramp_tables[index]);
+  tm_return->status = E_OK;
+}
+
+void Cust_tm_misc_param_write(T_TM_RETURN *tm_return, WORD16 index, UWORD16 value)
+{
+  switch (index)
+  {
+    case GPIOSTATE0:
+    case GPIODIR0:
+    case GPIOSTATE1:
+    case GPIODIR1:
+    case GPIOSTATE0P:
+    case GPIODIR0P:
+    case GPIOSTATE1P:
+    case GPIODIR1P:
+    {
+      tm_return->status = E_NOSUBSYS;
+      break;
+    }
+    case CONVERTED_ADC0:
+    case CONVERTED_ADC1:
+    case CONVERTED_ADC2:
+    case CONVERTED_ADC3:
+    case CONVERTED_ADC4:
+    case CONVERTED_ADC5:
+    case CONVERTED_ADC6:
+    case CONVERTED_ADC7:
+    case CONVERTED_ADC8:
+    {
+      adc.converted[index - CONVERTED_ADC0] = value;
+      tm_return->status = E_OK;
+      break;
+    }
+    
+    case RAW_ADC0:
+    case RAW_ADC1:
+    case RAW_ADC2:
+    case RAW_ADC3:
+    case RAW_ADC4:
+    case RAW_ADC5:
+    case RAW_ADC6:
+    case RAW_ADC7:
+    case RAW_ADC8:
+    {
+      adc.raw[index - RAW_ADC0]  = value;
+      tm_return->status = E_OK;
+      break;
+    }
+    
+    case ADC0_COEFF_A:
+    case ADC1_COEFF_A:
+    case ADC2_COEFF_A:
+    case ADC3_COEFF_A:
+    case ADC4_COEFF_A:
+    case ADC5_COEFF_A:
+    case ADC6_COEFF_A:
+    case ADC7_COEFF_A:
+    case ADC8_COEFF_A:
+    {
+      adc_cal.a[index - ADC0_COEFF_A]  = value;
+      tm_return->status = E_OK;
+      break;
+    }
+    
+    case ADC0_COEFF_B:
+    case ADC1_COEFF_B:
+    case ADC2_COEFF_B:
+    case ADC3_COEFF_B:
+    case ADC4_COEFF_B:
+    case ADC5_COEFF_B:
+    case ADC6_COEFF_B:
+    case ADC7_COEFF_B:
+    case ADC8_COEFF_B:
+    {
+      adc_cal.b[index - ADC0_COEFF_B]  = value;
+      tm_return->status = E_OK;
+      break;
+    }
+    case SLEEP_MODE:
+    {
+      power_down_config((UWORD8)value, UWIRE_CLK_CUT); //glowing,2004-6-17, import from M188
+      tm_return->status = E_NOSUBSYS;
+      break;
+	}
+    default:
+    {
+      tm_return->status = E_BADINDEX;
+      break;
+    }
+  } // end switch
+}
+
+void Cust_tm_misc_param_read(T_TM_RETURN *tm_return, WORD16 index)
+{
+  volatile UWORD16 value;
+
+  switch (index)
+  {
+    case GPIOSTATE0:
+    case GPIODIR0:
+    case GPIOSTATE1:
+    case GPIODIR1:
+    case GPIOSTATE0P:
+    case GPIODIR0P:
+    case GPIOSTATE1P:
+    case GPIODIR1P:
+    {
+      tm_return->status = E_NOSUBSYS;
+      tm_return->size = 0;
+      return;
+    }
+    case CONVERTED_ADC0:
+    case CONVERTED_ADC1:
+    case CONVERTED_ADC2:
+    case CONVERTED_ADC3:
+    case CONVERTED_ADC4:
+    case CONVERTED_ADC5:
+    case CONVERTED_ADC6:
+    case CONVERTED_ADC7:
+    case CONVERTED_ADC8:
+    {
+      value = adc.converted[index - CONVERTED_ADC0];
+      break;
+    }
+    case RAW_ADC0:
+    case RAW_ADC1:
+    case RAW_ADC2:
+    case RAW_ADC3:
+    case RAW_ADC4:
+    case RAW_ADC5:
+    case RAW_ADC6:
+    case RAW_ADC7:
+    case RAW_ADC8:
+    {
+      value = adc.raw[index - RAW_ADC0];
+      break;
+    }
+    case ADC0_COEFF_A:
+    case ADC1_COEFF_A:
+    case ADC2_COEFF_A:
+    case ADC3_COEFF_A:
+    case ADC4_COEFF_A:
+    case ADC5_COEFF_A:
+    case ADC6_COEFF_A:
+    case ADC7_COEFF_A:
+    case ADC8_COEFF_A:
+    {
+      value = adc_cal.a[index - ADC0_COEFF_A];
+      break;
+    }
+    case ADC0_COEFF_B:
+    case ADC1_COEFF_B:
+    case ADC2_COEFF_B:
+    case ADC3_COEFF_B:
+    case ADC4_COEFF_B:
+    case ADC5_COEFF_B:
+    case ADC6_COEFF_B:
+    case ADC7_COEFF_B:
+    case ADC8_COEFF_B:
+    {
+      value = adc_cal.b[index - ADC0_COEFF_B];
+      break;
+    }
+    case SLEEP_MODE:
+    {
+      tm_return->status = E_NOSUBSYS;
+      tm_return->size = 0;
+      return;
+    }
+    default:
+    {
+      tm_return->status = E_BADINDEX;
+      tm_return->size = 0;
+      return;
+    }
+  } // end switch
+
+  memcpy(tm_return->result, (UWORD8 *)&value, 2);
+  tm_return->size = 2;
+  tm_return->status = E_OK;
+}
+
+void Cust_tm_misc_enable(T_TM_RETURN *tm_return, WORD16 action)
+{
+    UWORD8 status;
+  
+    // FIXME: This enum really should go into testmode header file.
+    enum ME_CFG_WRITE_E {
+        CFG_WRITE_MKDIRS   = 100,
+        CFG_WRITE_RF_CAL   = 102,
+        CFG_WRITE_RF_CFG   = 103,
+        CFG_WRITE_TX_CAL   = 104,
+        CFG_WRITE_TX_CFG   = 105,
+        CFG_WRITE_RX_CAL   = 106,
+        CFG_WRITE_RX_CFG   = 107,
+        CFG_WRITE_SYS_CAL  = 108,
+        CFG_WRITE_SYS_CFG  = 109
+  };
+
+  tm_return->size = 0;
+  tm_return->index = action;
+  tm_return->status = E_OK;
+
+    // FIXME: This code should actually be in misc_enable()
+  switch(action)
+  {
+    case CFG_WRITE_MKDIRS:
+        ffs_mkdir("/gsm");
+        ffs_mkdir("/pcm");
+        ffs_mkdir("/sys");
+        ffs_mkdir("/mmi");
+        ffs_mkdir("/vos");
+        ffs_mkdir("/var");
+        ffs_mkdir("/gsm/rf");
+        ffs_mkdir("/gsm/com");
+        ffs_mkdir("/vos/vm");
+        ffs_mkdir("/vos/vrm");
+        ffs_mkdir("/vos/vrp");
+        ffs_mkdir("/var/log");
+        ffs_mkdir("/var/tst");
+        ffs_mkdir("/gsm/rf/tx");
+        ffs_mkdir("/gsm/rf/rx");
+      break;
+    case CFG_WRITE_RF_CAL:   config_ffs_write('f'); break;
+    case CFG_WRITE_RF_CFG:   config_ffs_write('F'); break;
+    case CFG_WRITE_TX_CAL:   config_ffs_write('t'); break;
+    case CFG_WRITE_TX_CFG:   config_ffs_write('T'); break;
+    case CFG_WRITE_RX_CAL:   config_ffs_write('r'); break;
+    case CFG_WRITE_RX_CFG:   config_ffs_write('R'); break;
+    case CFG_WRITE_SYS_CAL:  config_ffs_write('s'); break;
+    case CFG_WRITE_SYS_CFG:  config_ffs_write('S'); break;
+    default:
+      tm_return->status = E_BADINDEX;
+    }
+}
+
+void Cust_tm_special_param_write(T_TM_RETURN *tm_return, WORD16 index, UWORD16 value)
+{
+#if 0  //glowing,2004-06-17, comment
+  tm_return->size = 0;
+  tm_return->index = index;
+  tm_return->status = E_NOSYS;
+#endif
+//glowing,2004-06-17,import from M188
+	volatile int status;
+	extern void SetUserBackGround(short value);	//chenjun add 2003-01-24
+
+	switch ( index )
+	{
+		case LCD_SWITCH://lcd on/off; value=1 is lcd on, PASS, Ref. l1tm_cust_add.c
+			ctrlcd(value);
+			break;
+
+			//case LED_SWITCH://led on/off; value=1 is led on
+			//	ctrled(value);
+			//	break;
+		case BACKLIGHT_SWITCH://backlight on/off; value=1 is on, PASS
+			ctrbacklight(value);
+			break;
+		case VIBRATOR_CHECK://vibrator on/off; value =1 is on, PASS
+			ctrvibrator(value);
+			break;
+			//case BUZZER_CHECK://buzzer on/off; value =1 is on, No buzzer in MI188, Jeffrey, 04/01/04
+			//	ctrbuzzer(value);
+			//	break;
+		case TELL_SIMPHB_NUM:
+			tell_simphb_num(value);
+			g_pcsyncstatus=1;
+			break;
+		case SET_SLEEPMODE:
+			power_down_config(value, UWIRE_CLK_CUT);
+			break;
+		case TELL_SMSFILE_NUM:
+			tell_smsFile_num(value);
+			g_pcsyncstatus=1;
+			break;
+		case DEL_SIM_SMS:
+			del_sim_sms(value);
+			g_pcsyncstatus=1;
+			break;
+		case CHANGE_SIM_SMS:
+			change_sim_sms(value);
+			g_pcsyncstatus=1;
+			break;
+		case TELL_NVMPHB_NUM:
+			tell_nvmphb_num(value);
+			g_pcsyncstatus=1;
+			break;
+		case TRACE_AUDIOTASK://wms added 03-03-20
+			trace_audio_task();
+			break;
+
+		case WRITE_TESTNUMBER: // Jeffrey, for production test, 04/06/04
+			{
+				short ret;
+				ret = write_TestNumber(value);
+				if ( ret )
+				{
+					tm_return->size = 0;
+					tm_return->index = index;
+					memcpy(tm_return->result, (UWORD8 *)&ret, 2);
+					tm_return->status = E_NOSUBSYS;
+					return;
+				}
+				tm_return->size = 2;
+				memcpy(tm_return->result, (UWORD8 *)&value, 2);
+				tm_return->index = index;
+				tm_return->status = E_OK;
+			}
+			break;
+
+
+/*
+		  //chenjun add 2003-01-23  begin  
+		case SET_USUAL_RING:
+			
+			SetEnvironRing(0,(short)value);
+			break;
+		
+		case SET_OUTDOOR_RING:
+			SetEnvironRing(1,(short)value);
+			break;
+		
+		case SET_MEETING_RING:
+			SetEnvironRing(2,(short)value);
+			break;
+		
+		case SET_INCAR_RING:
+			SetEnvironRing(3,(short)value);
+			break;
+		
+		   
+		  //chenjun add 2003-01-23  over	
+		*/  
+		case SET_USER_BACK:
+			
+		 //SPI_WriteTX_MSB(0x0A << 6 |TOGBR1);      // Initialize transmit register. This transmission
+ 		 //SPI_StartWrite();                        // enables selected OMEGA modules  
+ 		 //glowing,2004-06-17, use the new spi api
+#if 0 		 
+		 SPI_WRITE_TX_MSB(0x0A << 6 | TOGBR1);      // Initialize transmit register. This transmission
+ 		 SPI_START_WRITE                        // enables selected OMEGA modules  
+		 while(((status = Spi->SPI_CTRL_STAT_UN.SPI_CTRL_STAT_ST.SPI_REG_STATUS) & WE_ST) == 0);
+#else
+		 ABB_Write_Register_on_page( PAGE0, TOGBR1, 0x0A );
+#endif
+
+         ABB_UlMute(0);
+         ABB_DlMute(0);
+		 ABB_SideTone(175);
+		 dspl_TextOut(0, 0, 0, "loop audio test");
+		SetUserBackGround(value);
+		break;
+/* glowing,2004-06-17, we doesn't define DRVPCTMTRACE.
+ * some of the following functions doesn't define
+ * in this version, so let it be.
+ */
+#ifdef DRVPCTMTRACE    
+		case TRACE_CMD:
+			switch ( value )
+			{
+				/*0~9 for hall*/
+				case 0:	//hallstatusflag
+					TraceHallVarvalue();
+					break;
+				case 1:	//hall mask register
+					TraceHallMaskRegister();
+					break;
+				case 2:	//hall status register
+					TraceHallOnOff();
+					break;
+				case 3:	//hall 
+					AI_MaskIT(2);
+					break;
+				case 4:	//hall 
+					AI_UnmaskIT(2);
+					break;
+				case 5:	//hall 
+					break;
+				case 6:	//hall 
+					break;
+				case 7:	//hall 
+					break;
+				case 8:	//hall 
+					break;
+				case 9:	//hall 
+					break;
+
+					/*10~19 for charger*/
+				case 10: //pwr_status
+					TracePwrstatus();
+					break;
+				case 11: //ÍⲿÖжÏmask
+					break;
+				case 12: //mmiµç³ØÐÅÏ¢
+					break;
+				case 13: //µç³Øµçѹ
+					RivieraTrace_Chunhui("_GetBatteryVoltage(1)=", GetBatteryVoltage(1));
+					break;
+				case 14: //³äµçµçѹ
+					GetChargerVoltage();
+					break;
+				case 15: //³äµçµçÁ÷
+					GetChargerCurrent();
+					break;
+				case 16: //charger
+					break;
+				case 17: //charger 
+					break;
+				case 18: //charger
+					break;
+				case 19: //charger 
+					break;
+
+					/*20~29 for keypad*/
+				case 20: //keypad mask
+					TraceKeypadMaskRegister();
+					break;
+				case 21: //keypad
+					RivieraTrace_Chunhui("kpd_scan_keypad", kpd_scan_keypad());
+					break;
+				case 22: //keypad
+					Trace_kbd_gpio_int();
+					break;
+				case 23: //keypad
+					kpd_acknowledge_key_pressed();
+					break;
+				case 24: //keypad
+					AI_MaskIT(1);
+					break;
+				case 25: //keypad 
+					Set_g_interrupt_to_zero();
+					break;
+				case 26: //keypad 
+					Trace_g_interrupt_value();
+					break;
+				case 27: //keypad 
+					break;
+				case 28: //keypad 
+					break;
+				case 29: //keypad
+					break;
+
+					/*30~39 for lamp*/
+				case 30: //lamp
+					break;
+				case 31: //lamp
+					break;
+				case 32: //lamp
+					break;
+				case 33: //lamp
+					break;
+				case 34: //lamp
+					break;
+				case 35: //lamp
+					break;
+				case 36: //lamp 
+					break;
+				case 37: //lamp 
+					break;
+				case 38: //lamp 
+					break;
+				case 39: //lamp 
+					break;
+
+					/*40~49 for lcd*/
+				case 40: //lcd not use ,instead of using se 10 by ganch
+					//µ¹ÖÃ				
+					break;
+				case 41: //lcd
+					//Ó²¼þreset
+					RivieraTrace_Chunhui("_now call resetlcd()_",0);
+					ResetLCD();
+					break;
+				case 42: //lcd
+					//lcdÈí¼þreset
+					RivieraTrace_Chunhui("_now call ColorLcd_Init(1)_",0);              
+					ColorLCD_Init(1);
+					break;
+				case 43: //lcd
+					//¿´³õʼ»¯lcdÊÇ·ñ³É¹¦
+					break;
+				case 44: //lcd
+					break;
+				case 45: //lcd 
+					break;
+				case 46: //lcd 
+					break;
+				case 47: //lcd 
+					break;
+				case 48: //lcd 
+					break;
+				case 49: //lcd
+					break;
+
+					/*50~59 for flash*/
+				case 50: //flash
+					break;
+				case 51: //flash
+					break;
+				case 52: //flash
+					break;
+				case 53: //flash
+					break;
+				case 54: //flash 
+					break;
+				case 55: //flash 
+					break;
+				case 56: //flash 
+					break;
+				case 57: //flash 
+					break;
+				case 58: //flash
+					break;
+				case 59: //flash
+					break;
+				case 60:
+					MmiTrace("60");
+					print_mfw_link();
+					break;
+				default:
+					break;
+			}
+			break;
+
+
+
+#endif
+		case CALL_EMERGENCY:
+			if(value == 1)	/* dialling 112 */
+			{
+				/*if(sAT_Dn(0, "112", -1, -1, 0) != 1)*/	/* return 1 if dialling in progress */
+				if(cm_mo_call("112", 1) != 1)
+				{					
+					tm_return->index = index;
+					tm_return->size = 0;
+					tm_return->status = E_NOSYS;
+					return;
+				}
+			}
+			else	/* hang up */
+			{
+				cm_disconnect(1);
+			}
+			break;
+		case SET_ENCRYPT_KEY:
+			{
+			short ret;
+/* 2004/06/08, zhq ,commit it because it is for test only.
+			char tmpstr[50] = {0};
+			char tmpstr2[50] = {0};
+			strcpy(tmpstr, "value=");
+			Num2Str(value, tmpstr2);
+			strcat(tmpstr,tmpstr2);
+			dspl_TextOut(0, 0, 0, tmpstr);
+*/
+			ret = Set_Encrypt_Key(value);
+			if ( ret )
+				{
+					tm_return->size = 0;
+					tm_return->index = index;
+					memcpy(tm_return->result, (UWORD8 *)&ret, 2);
+					tm_return->status = E_NOSUBSYS;
+					return;
+				}
+				tm_return->size = 2;
+				memcpy(tm_return->result, (UWORD8 *)&value, 2);
+				tm_return->index = index;
+				tm_return->status = E_OK;
+			}
+			break;
+		case AUDIO_LOOP:
+			if(value == 1)
+			Audio_Loop_Test_pctm_start();
+			else
+			Audio_Loop_Test_pctm_stop();
+			break;
+		case SPEAK_RING:
+			if(value == 1)
+			Speaker_Vibrator_Test_Start();
+			else
+			Speaker_Vibrator_Test_Stop();
+			break;
+		case SET_MAINBOARD_TYPE:
+			{
+/* 2004/06/08, zhq, add for production test purpose. 
+0 indicate 188 serial of mainboard.
+1 indicate 288 serial of mainboard.
+2 indicate 388 serial of mainboard.
+3 indicate 588 serial of mainboard.
+etc.
+*/
+			short ret;
+			ret = Set_MainboardType(value);
+			if ( ret )
+				{
+					tm_return->size = 0;
+					tm_return->index = index;
+					memcpy(tm_return->result, (UWORD8 *)&ret, 2);
+					tm_return->status = E_NOSUBSYS;
+					return;
+				}
+				tm_return->size = 2;
+				memcpy(tm_return->result, (UWORD8 *)&value, 2);
+				tm_return->index = index;
+				tm_return->status = E_OK;
+			}
+			break;
+
+			
+
+		default:
+			break;
+	}
+
+#ifdef DRVPCTMTRACE  //ljq add for trace_pctm command 2003/1/8 according to ganch
+
+	tm_return->index = index;
+	memcpy(tm_return->result, (UWORD8 *)&value, 1);
+	tm_return->size = 1;
+
+	tm_return->status = E_OK;
+
+#else  
+	MmiTrace("return ok");
+	tm_return->size = 0;
+	tm_return->index = index;
+	tm_return->status = E_OK;
+#endif  	
+
+//glowing,2004-06-17,end of import
+}
+
+void Cust_tm_special_param_read(T_TM_RETURN *tm_return, WORD16 index)
+{
+#if 0
+  tm_return->size = 0;
+  tm_return->index = index;
+  tm_return->status = E_NOSYS;
+#endif
+//glowing,2004-06-17,import from M188
+	extern void GetUserBackGround(short*  value); //chenjun add 2003-01-24
+	extern char *ver;
+	volatile UWORD16 value=0;
+	
+	switch ( index )
+	{
+		case SIM_CHECK://check sim card ; if check sim card ok , return 1 
+			value = checksim(); 
+			break;
+		case NETWORK_CHECK://check network ; if network  ok , return 1 
+			value = checknetavail();
+			break;
+		case READ_SIM_PHB:
+			value= read_sim_phb();
+			g_pcsyncstatus=1;
+			break;
+		case WRITE_SIM_PHB:
+			value=write_sim_phb();
+			g_pcsyncstatus=1;
+			break;
+		case READ_SIM_SMS:
+			value=read_sim_sms();
+			g_pcsyncstatus=1;
+			break;
+		case READ_NEW_SMS:
+			value=read_new_sms();
+			g_pcsyncstatus=1;
+			break;
+		case SEND_SMS:
+			value=send_sms();
+			g_pcsyncstatus=1;
+			break;
+
+		case READ_TESTNUMBER://Jeffrey, read test number for production test, 04/06/04
+			{			
+				int ret = read_TestNumber(&value);
+				
+				if ( ret < 0 )
+				{
+					tm_return->size = 0;
+					tm_return->index = index;
+					memcpy(tm_return->result, &ret, sizeof(int));
+					tm_return->status = E_AGAIN;
+					return;
+				}			
+			}
+			break;
+
+		case GET_USER_BACK:
+			{
+				char v[12];
+				GetUserBackGround((short*)&value);
+				sprintf(v, "User BG=%d", value);
+				dspl_TextOut(0, 0, 0, v);
+			}
+			break;//chenjun 0227 add break
+		case  READ_PBOPTION:
+			flash_PBOtherRead("PBOption");
+			break;	 //chenjun add 0227 	
+		case GET_ENCRYPT_KEY:
+			{
+			short ret;
+			char tmpstr[50] = {0};
+			char tmpstr2[50] = {0};
+			
+			ret = Get_Encrypt_Key(&value);
+
+/* 2004/06/08, zhq ,commit it because it is for test only.
+			strcpy(tmpstr, "value=");
+			Num2Str(value, tmpstr2);
+			strcat(tmpstr,tmpstr2);
+			dspl_TextOut(0, 0, 0, tmpstr);
+*/
+			tm_return->size = 2;
+			memcpy(tm_return->result, (UWORD8 *)&value, 2);
+			tm_return->index = index;
+			tm_return->status = E_OK;
+			}
+			break;
+		case GET_MAINBOARD_TYPE:
+		{
+/* 2004/06/08, zhq, add for production test purpose. 
+0 indicate 188 serial of mainboard.
+1 indicate 288 serial of mainboard.
+2 indicate 388 serial of mainboard.
+3 indicate 588 serial of mainboard.
+etc.
+*/			
+			int ret ;
+			char tmpstr[50] = {0};
+			char tmpstr2[50] = {0};
+			
+			ret = Get_MainboardType(&value);
+
+/* 2004/06/08, zhq ,commit it because it is for test only.
+			strcpy(tmpstr, "value=");
+			Num2Str(value, tmpstr2);
+			strcat(tmpstr,tmpstr2);
+			dspl_TextOut(0, 0, 0, tmpstr);
+*/
+			if ( ret < 0 )
+			{
+				tm_return->size = 0;
+				tm_return->index = index;
+				memcpy(tm_return->result, &ret, sizeof(int));
+				tm_return->status = E_AGAIN;
+				return;
+			}			
+		}
+			break;
+		default:
+			tm_return->index = index;
+			tm_return->status = E_OK;
+			tm_return->size = strlen(ver);
+			memcpy((void*)tm_return->result, (void*)ver, tm_return->size);
+			return;
+			break;
+	}
+
+	tm_return->index = index;
+	memcpy(tm_return->result, (UWORD8 *)&value, 2);
+	tm_return->size = 2;
+
+	tm_return->status = E_OK;
+
+//glowing,2004-06-17,end of import
+
+}
+
+void Cust_tm_special_table_write(T_TM_RETURN *tm_return, WORD8 index, UWORD8 size, UWORD8 table[])
+{
+#if 0
+  tm_return->size = 0;
+  tm_return->index = index;
+  tm_return->status = E_NOSYS;
+#endif
+//glowing,2004-06-17,import from M188
+	extern void SetRingAlarmGroupRing( unsigned char data[]); //chenjun add 2003-01-23
+
+	WORD8 coef_no;
+	WORD16 *addr;
+	WORD16 data;
+	extern T_L1A_L1S_COM l1a_l1s_com; // Get access to DSP configuration
+	extern T_L1S_DSP_COM l1s_dsp_com; // Get access to DSP configuration
+
+	int nRetval;
+	UWORD16 value=0;
+	UWORD32 Reg;
+	volatile UWORD16        *pReg;
+
+	tm_return->size = 0;
+	tm_return->index = index;
+	tm_return->status = E_NOSYS;
+
+
+
+	switch ( index )
+	{
+		//by xmzhou to test audio(FIR,echo) according to Jesper--------------------------
+		case 1:// PCTM command to update DL FIR: STW 1 [coef 1] [coef 2] .. [coef 31]
+			{  // First initialize PCTM by writing: STW -s 1 "%31[%y %]"
+				if ( size == (31*2) )
+				{
+					for ( coef_no=0; coef_no<31; coef_no++ )
+#if (DSP == 33)
+						l1s_dsp_com.dsp_param_ptr->a_fir31_downlink[coef_no] = (table[coef_no*2+1]<<8) | table[coef_no*2];
+#else
+//glowing,2004-06-17,modify
+//						l1s_dsp_com.dsp_ndb_ptr->a_fir31_downlink[coef_no] = (table[coef_no*2+1]<<8) | table[coef_no*2];
+						l1s_dsp_com.dsp_param_ptr->a_fir31_downlink[coef_no] = (table[coef_no*2+1]<<8) | table[coef_no*2];
+#endif
+					tm_return->status = E_OK;
+				}
+				else
+					tm_return->status = E_BADSIZE;
+			}
+			break;
+		case 2:// PCTM command to update UL FIR: STW 2 [coef 1] [coef 2] .. [coef 31]
+			{  // First initialize PCTM by writing: STW -s 2 "%31[%y %]"
+				if ( size == (31*2) )
+				{
+					for ( coef_no=0; coef_no<31; coef_no++ )
+#if (DSP == 33)
+						l1s_dsp_com.dsp_param_ptr->a_fir31_uplink[coef_no] = (table[coef_no*2+1]<<8) | table[coef_no*2];
+#else
+//glowing,2004-06-17,modify
+//						l1s_dsp_com.dsp_ndb_ptr->a_fir31_uplink[coef_no] = (table[coef_no*2+1]<<8) | table[coef_no*2];
+						l1s_dsp_com.dsp_param_ptr->a_fir31_uplink[coef_no] = (table[coef_no*2+1]<<8) | table[coef_no*2];
+#endif
+					tm_return->status = E_OK;
+				}
+				else
+					tm_return->status = E_BADSIZE;
+			}
+			break;
+		case 3:// PCTM command to update AEC/Noise Reduction algo.: STW 3 [value]
+			{
+				l1s_dsp_com.dsp_ndb_ptr->d_aec_ctrl = (table[1]<<8) | table[0];	   // aec/nr control variable
+				l1a_l1s_com.aec_task.command.start = FALSE;		  // Start the AEC with new setting
+				tm_return->status = E_OK;
+			}
+			break;
+			//end of xmzhou add-----------------------------------------------------------
+		case WRITE_REG_TEST:
+			Reg=(table[0]<<24) | (table[1]<<16) |(table[2]<<8) |(table[3]);
+			pReg=(UWORD16 *)Reg;
+			*pReg=(table[4]<<8) |table[5];
+
+			tm_return->size = 2;
+			memcpy(tm_return->result, (UWORD8 *)&value, 2);
+			tm_return->index = index;
+			tm_return->status = E_OK;
+			break;
+		case READ_REG_TEST:
+			Reg=(table[0]<<24) | (table[1]<<16) |(table[2]<<8) |(table[3]);
+			pReg=(UWORD16 *)Reg;
+			value=*pReg;
+			tm_return->size = 2;
+			memcpy(tm_return->result, (UWORD8 *)&value, 2);
+			tm_return->index = index;
+			tm_return->status = E_OK;
+			break;
+
+
+		case WRITE_IMEI://write Imei  
+			nRetval=write_imei(&table[0]);
+			if ( nRetval==FALSE )
+			{
+				tm_return->size = 0;
+				tm_return->index = index;
+				tm_return->status = E_NOSUBSYS;
+				return;
+			}
+			tm_return->size = 2;
+			memcpy(tm_return->result, (UWORD8 *)&value, 2);
+			tm_return->index = index;
+			tm_return->status = E_OK;
+			break;
+		case WRITE_SERIALNUMBER://write serial number
+			nRetval=write_SerialNumber(&table[0]);
+			if ( nRetval==FALSE )
+			{
+				tm_return->size = 0;
+				tm_return->index = index;
+				tm_return->status = E_NOSUBSYS;
+				return;
+			}
+			tm_return->size = 2;
+			memcpy(tm_return->result, (UWORD8 *)&value, 2);
+			tm_return->index = index;
+			tm_return->status = E_OK;
+			break;
+		case KEY_SIMULATION:
+			nRetval=key_simulation(size,&table[0]);
+			if ( nRetval==FALSE )
+			{
+				tm_return->size = 0;
+				tm_return->index = index;
+				tm_return->status = E_NOSUBSYS;
+				return;
+			}
+			tm_return->size = 2;
+			memcpy(tm_return->result, (UWORD8 *)&value, 2);
+			tm_return->index = index;
+			tm_return->status = E_OK;
+			break;
+		case SET_RTC:
+			{
+				T_RVF_RET ret;
+				ret=RTC_SetDateTime(*((T_RTC_DATE_TIME *)table));
+				if ( ret!=RV_OK )
+				{
+					tm_return->size = 0;
+					tm_return->index = index;
+					tm_return->status = E_NOSUBSYS;
+					return;
+				}
+				tm_return->size = 2;
+				memcpy(tm_return->result, (UWORD8 *)&value, 2);
+				tm_return->index = index;
+				tm_return->status = E_OK;
+			}
+			break;
+
+
+		case SET_CUR_RING:	  //chenjun add 2003-01-23 to set ringtype, alarmtype and grouping ringtype
+			SetRingAlarmGroupRing( table);
+			tm_return->size = 18;
+			tm_return->index = index;
+			tm_return->status = E_OK;
+			break;
+		case WRITE_CMD_PW:
+			tm_return->size = 2;
+			memcpy(tm_return->result, (UWORD8 *)&value, 2);
+			tm_return->index = index;
+			if ( (strncmp((char *)table,CmdPW,6)==0) )
+			{
+				OpenCmd=1;
+				tm_return->status = E_OK;
+				return ;
+			}
+			else
+			{
+				OpenCmd=0;
+				tm_return->status = E_NOSYS;
+				return ;
+			}
+			//end of hxl add,2003-4-14
+			break;
+		default:
+			tm_return->size = 0;
+			tm_return->index = index;
+			tm_return->status = E_BADCID;
+			return;
+	}
+
+//glowing,2004-06-17,end of import
+
+}
+
+void Cust_tm_special_table_read(T_TM_RETURN *tm_return, WORD8 index)
+{
+#if 0
+  tm_return->size = 0;
+  tm_return->index = index;
+  tm_return->status = E_NOSYS;
+#endif  
+	extern void GetRingAlarmGroupRing(char* data );//chenjun add 2003-01-23
+	extern char *ver, *date;
+	
+	char value[30];
+	int nRetval;
+
+	switch ( index )
+	{
+		case READ_IMEI://read Imei  
+			nRetval=get_imei(value);
+
+			if ( nRetval==FALSE )
+			{
+				tm_return->size = 0;
+				tm_return->index = index;
+				tm_return->status = E_NOSUBSYS;
+			}
+			else
+			{
+				tm_return->size = 16;
+				memcpy(tm_return->result, value, tm_return->size);
+				tm_return->index = index;
+				tm_return->status = E_OK;
+			}
+
+			break;
+		case READ_SERIALNUMBER://read serial number
+			nRetval=read_SerialNumber(value);
+
+			if ( nRetval==FALSE )
+			{
+				tm_return->size = 0;
+				tm_return->index = index;
+				tm_return->status = E_NOSUBSYS;
+			}
+			else
+			{
+				tm_return->size = 8;
+				memcpy(tm_return->result, value, tm_return->size);
+				tm_return->index = index;
+				tm_return->status = E_OK;
+			}
+			break;
+		case READ_RTC:
+			{
+				//		nRetval=read_rtc(value);
+				T_RVF_RET ret;
+				T_RTC_DATE_TIME data_time;
+				ret=RTC_GetDateTime(&data_time);
+
+				if ( ret!=RV_OK )
+				{
+					tm_return->size = 0;
+					tm_return->index = index;
+					tm_return->status = E_NOSUBSYS;
+					return;
+				}
+				else
+				{
+					sprintf(value,"%2d:%2d:%2d %2d-%2d-%2d %2d;%d;%d",
+							data_time.hour,
+							data_time.minute,
+							data_time.second,
+							data_time.year,
+							data_time.month,
+							data_time.day,
+							data_time.wday,
+							data_time.mode_12_hour,
+							data_time.PM_flag);
+					value[24]=0;
+
+					tm_return->size = 25;
+					memcpy(tm_return->result, value, tm_return->size);
+					tm_return->index = index;
+					tm_return->status = E_OK;
+				}
+			}
+			break;
+			//zhonghz, for read rtc control REG
+		case READ_RTC_STATUS:
+			{
+				T_RVF_RET ret;
+				T_RTC_STATUS rtc_status;
+				char tmpvalue[100];
+				memset(tmpvalue,0,100);
+				ret=RTC_GetStatus(&rtc_status);
+
+				if ( ret!=RV_OK )
+				{
+					tm_return->size = 0;
+					tm_return->index = index;
+					tm_return->status = E_NOSUBSYS;
+					return;
+				}
+				else
+				{
+					sprintf(tmpvalue,"ctrl:0x%2x,stat:0x%2x,int:0x%2x,cl:0x%2x,cm:0x%2x",
+							rtc_status.ctrl_reg,
+							rtc_status.stat_reg,
+							rtc_status.int_reg,
+							rtc_status.cmpl_reg,
+							rtc_status.cmpm_reg);
+					tmpvalue[45]=0;
+					tm_return->size = 44;
+					memcpy(tm_return->result, tmpvalue, tm_return->size);
+					tm_return->index = index;
+					tm_return->status = E_OK;
+				}
+			}
+			break;
+		case CHECK_FILE_STATUS:
+			{
+				UWORD8  size;
+				size=IsPcCmdExcuteEnd(value); 
+
+				tm_return->size = size;
+				memcpy(tm_return->result, value, tm_return->size);
+				tm_return->index = index;
+				tm_return->status = E_OK;
+
+				MmiTraceInt(value[0]);
+				MmiTraceInt(value[1]);
+				MmiTraceInt(value[2]);
+				MmiTraceInt(value[3]);
+				MmiTraceInt(size);
+			}
+			
+			g_pcsyncstatus=1;
+			break;
+
+		case  GET_CUR_RING:	  //chenjun add 2003-01-23
+			GetRingAlarmGroupRing(value);
+			tm_return->size =18;
+			memcpy(tm_return->result, (unsigned char*)value, 18);
+			tm_return->index = index;
+			tm_return->status = E_OK;
+			break;
+
+		case READ_SWVER:		
+			tm_return->index = index;
+			tm_return->status = E_OK;
+			tm_return->size = strlen(ver)+strlen(date);			
+			memcpy((void*)tm_return->result, (void*)ver, strlen(ver));
+			memcpy((void*)(tm_return->result + strlen(ver)), (void*)date, strlen(date));
+			return;		
+
+		default:
+			tm_return->size = 0;
+			tm_return->index = index;
+			tm_return->status = E_BADCID;
+			break;
+	}
+
+}
+
+void Cust_tm_special_enable(T_TM_RETURN *tm_return, WORD16 action)
+{
+#if 0
+  tm_return->size = 0;
+  tm_return->index = action;
+  tm_return->status = E_NOSYS;
+#endif
+	//Bob added 03/21
+	int i=0,j=0;
+	//char name[8];
+	char *ptr;
+	tm_return->size = 0;
+	tm_return->index = action;
+	tm_return->status = E_NOSYS;
+
+	//by xmzhou to enable DAI test according to Jesper
+	if ( action == 1 ) // PCTM command to activate MCSI: SE 1
+	{
+		*((volatile UINT16 *) 0xfffef00a) &= 0xfe1f; // Switch GPIO to MCSI (DAI) mode
+		tm_return->status = E_OK;
+	}
+	//by xmzhou to enable LCD backlight
+	if ( action == 2 )
+	{
+		ctrlcd(255); //open LCD backlight
+		tm_return->status = E_OK;
+	}
+
+	//by xmzhou to disable LCD backlight
+	if ( action == 3 )
+	{
+		ctrlcd(0); //disable LCD backlight
+		tm_return->status = E_OK;
+	}
+
+	//by xmhout to test l1 engineering mode rx level and quality
+	if ( action == 4 )
+	{
+		extern void layer1_em_get_rxlevqual(WORD32 *l1_rxlev_scell,WORD32 *l1_rxlev_dedic_sub,
+											WORD32 *l1_rxqual_dedic,WORD32 *l1_rxqual_dedic_sub);
+
+		WORD32 a,b,c,d;
+
+		layer1_em_get_rxlevqual(&a,&b,&c,&d);
+		tm_return->status = E_OK;
+	}
+
+	//by xmzhou to test l1 engineering mode l1_mode
+	if ( action == 5 )
+	{
+		extern void layer1_em_get_mode(WORD32 *l1_mode);
+
+		WORD32 a;
+
+		layer1_em_get_mode(&a);
+		tm_return->status = E_OK;
+	}
+
+	//by xmzhou to play melody E2 No1
+	if ( action == 6 )
+	{
+		//	extern void RingStart1(void);
+
+		// 	RingStart1();
+		tm_return->status = E_OK;
+	}
+	//by xmzhou to stop melody E2 No1
+	if ( action == 7 )
+	{
+		//xtern void RingStop1(void);
+
+		//ingStop1();
+		tm_return->status = E_OK;
+	}
+	//by xmzhou to play melody E2 No2
+	if ( action == 8 )
+	{
+		//extern void RingStart2(void);
+
+		//RingStart2();
+		tm_return->status = E_OK;
+	}
+	//by xmzhou to stop melody E2 No2
+	if ( action == 9 )
+	{
+//	extern void RingStop2(void);
+
+//	RingStop2();
+		tm_return->status = E_OK;
+	}
+	if ( action==10 )
+	{
+		extern void ColorLCDCommandRead(void);
+		ColorLCDCommandRead();
+		tm_return->status = E_OK;
+	}
+
+	/*control trace comand */
+	if ( action==11 )
+	{
+#if 0 //glowing,2004-06-17,comment	
+		extern UNSIGNED RivieraTraceFlag;
+		RivieraTraceFlag=1;
+#endif		
+		tm_return->status = E_OK;
+	}
+	/*control trace comand */
+	if ( action==12 )
+	{
+#if 0 //glowing,2004-06-17,comment	
+		extern UNSIGNED RivieraTraceFlag;
+		RivieraTraceFlag=0;
+#endif		
+		tm_return->status = E_OK;
+
+	}
+	if ( action == 20 )
+	{
+		// 	   extern void Mic_on();
+		Mic_on();        
+		tm_return->status = E_OK;
+	}
+	if ( action == 21 )
+	{
+		//	   extern void Mic_off();
+		Mic_off();
+		tm_return->status = E_OK;
+	}
+	if ( action == 22 )
+	{
+		Spk_on();
+		tm_return->status = E_OK;
+	}
+	if ( action == 23 )
+	{
+		Spk_off();
+		tm_return->status = E_OK;
+	}
+	if ( action == 24 )
+	{
+		Red_On();
+		tm_return->status = E_OK;
+	}
+	if ( action == 25 )
+	{
+		Red_Off();
+		tm_return->status = E_OK;
+	}
+	if ( action == 26 )
+	{
+		Green_On();
+		tm_return->status = E_OK;
+	}
+	if ( action == 27 )
+	{
+		Green_Off();
+		tm_return->status = E_OK;
+	}
+	if ( action == 28 )
+	{
+		Vibrator_on();
+		tm_return->status = E_OK;
+	}
+
+	if ( action == 29 )
+	{
+		Vibrator_off();
+		tm_return->status = E_OK;
+	}
+	if ( action == 30 )
+	{
+		Backlight_ON();
+		tm_return->status = E_OK;
+	}
+	if ( action == 31 )
+	{
+		Backlight_OFF();
+		tm_return->status = E_OK;
+	}
+	//end Bob added 01/25
+	if ( action == 32 )
+	{
+		SetMVol_DownLinkPGA(6); 
+		//StartMelody(0);
+		StartPlayingMelody2(0,0); //glowing,2003-12-23, use the yamaha api
+		tm_return->status = E_OK;
+	}
+	if ( action == 33 )
+	{
+		//StopMelody();
+		StopPlayingMelody2(); //glowing,2003-12-23, use the yamaha api
+		tm_return->status = E_OK;
+	}
+	if ( action==34 )	//ganchh 2003/3/15 for Layer1 and Riviera trace switch on
+	{
+#if 0 //glowing,2004-06-17,comment	
+		extern UWORD32 layer1_trace_mask;
+		extern UWORD32 riviera_trace_mask;
+		layer1_trace_mask=0xffffffff;//enable all the layer1 trace
+		riviera_trace_mask=0xffffffff;//enable all trace
+#endif		
+		tm_return->status = E_OK;
+	}
+	if ( action==35 )
+	{
+#if 0	//glowing,2004-06-17,comment
+		extern UWORD32 layer1_trace_mask;
+		extern UWORD32 riviera_trace_mask;
+		layer1_trace_mask=0x0; //disable all the layer1 trace
+		riviera_trace_mask=0x0;	//diable all trace
+#endif		
+		tm_return->status = E_OK;
+	}
+	if ( action == 50 )
+	{
+		GetTimerInfo();
+		tm_return->status = E_OK;
+	}
+	if ( action == 51 )
+	{
+		GetTaskInfo();
+		tm_return->status = E_OK;
+	}
+	if ( action ==52 )
+	{
+		// TestTimerInfo();
+		tm_return->status = E_OK;
+	}
+#if 0	
+	if ( action == 53 )
+	{
+		timer =  TMD_Active_Timers_List;
+		MmiTrace("T is:");
+		while ( i<8 )
+		{
+			app_timer =  (TM_APP_TCB *) timer -> tm_information;
+			expiration_routine =  app_timer -> tm_expiration_routine;
+			ptr=(((TM_APP_TCB *)app_timer)->tm_name);
+			for ( j=0;j<8;j++ )
+				Bobname[i][j]=*ptr++;  //app_timer->tm_name[j];pointer =  (((TC_TCB *) TCD_Current_Thread) -> tc_name);
+			//  MmiTrace(name);
+			MmiTraceInt(expiration_routine);
+			timer=(TM_TCB *)timer->tm_next_timer;
+			i++;
+			//     Bobtrace(name, ((TM_APP_TCB *)app_timer -> tm_expiration_routine));
+		}
+		tm_return->status = E_OK;
+	}
+	if ( action == 55 )
+	{
+
+		for ( i=0;i<8;i++ )
+			MmiTrace(Bobname[i]);
+		tm_return->status = E_OK;
+	}
+#endif	
+
+}
+
+void Cust_set_voicefir(void){
+#if 0	
+	int i;
+	extern T_L1S_DSP_COM l1s_dsp_com; // Get access to DSP configuration
+	for ( i=0; i<31; i++ )
+	{
+		l1s_dsp_com.dsp_param_ptr->a_fir31_downlink[i] =voice_a_fir31_downlink[i];
+	}
+#endif	
+}
+
+
+#endif // TESTMODE