T_TxIq_EPSK.cpp
上传用户:gelin96
上传日期:2017-01-08
资源大小:20993k
文件大小:69k
源码类别:

MTK

开发平台:

C++ Builder

  1. /*****************************************************************************
  2. *  Copyright Statement:
  3. *  --------------------
  4. *  This software is protected by Copyright and the information contained
  5. *  herein is confidential. The software may not be copied and the information
  6. *  contained herein may not be used or disclosed except with the written
  7. *  permission of MediaTek Inc. (C) 2001
  8. *
  9. *****************************************************************************/
  10. /*****************************************************************************
  11.  *
  12.  * Filename:
  13.  * ---------
  14.  *   T_TxIq_EPSK.cpp
  15.  *
  16.  * Project:
  17.  * --------
  18.  *   Maui META APP
  19.  *
  20.  * Description:
  21.  * ------------
  22.  *  EPSK TX IQ calibration source
  23.  *
  24.  * Author:
  25.  * -------
  26.  *  Andy Ueng (mtk00490)
  27.  *
  28.  *============================================================================
  29.  *             HISTORY
  30.  * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
  31.  *------------------------------------------------------------------------------
  32.  * $Revision$
  33.  * $Modtime$
  34.  * $Log$
  35.  *
  36.  *------------------------------------------------------------------------------
  37.  * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
  38.  *============================================================================
  39. ****************************************************************************/
  40. #include <assert.h>
  41. #include <math.h>
  42. #pragma hdrstop
  43. #ifndef _T_TXIQ_COMMON_H_
  44. #include "T_TxIq_common.h"
  45. #endif
  46. #ifndef _CAL_COMMON_H_
  47. #include "cal_common.h"
  48. #endif
  49. // misc
  50. #ifndef  _FT_UTILS_H_
  51. #include "ft_utils.h"
  52. #endif
  53. #ifndef  _BAND_UTILS_H_
  54. #include "band_utils.h"
  55. #endif
  56. #ifndef  _MATH_UTILS_H_
  57. #include "math_utils.h"
  58. #endif
  59. #ifndef  _AGE_MISC_H_
  60. #include "age_misc.h"
  61. #endif
  62. #ifndef  _GSM_UTILS_H_
  63. #include "gsm_utils.h"
  64. #endif
  65. #ifndef  _TIME_UTILS_H_
  66. #include "time_utils.h"
  67. #endif
  68. // equipment
  69. #ifndef _AGECOMMON_H_
  70. #include "agecommon.h"
  71. #endif
  72. #ifndef _AGE1968A_H_
  73. #include "age1968a.h"
  74. #endif
  75. // TX phase error calibration
  76. #ifndef _RF_OFFSET_IQ_SWEEP_INIT_AGE8960_H_
  77. #include "rf_offset_iq_sweep_init_age8960.h"
  78. #endif
  79. #ifndef  _RF_TXIQ_H_
  80. #include "rf_txiq.h"
  81. #endif
  82. // form
  83. #ifndef _META_FACTORY_H_
  84. #include "META_Factory.h"
  85. #endif
  86. // call back
  87. #ifndef _META_FACTORY_NVRAM_CB_H_
  88. #include "meta_factory_nvram_cb.h"
  89. #endif
  90. #ifndef _META_FACTORY_RF_CB_H_
  91. #include "meta_factory_rf_cb.h"
  92. #endif
  93. //----------------------------------------------------------------------------
  94. // phase error
  95. extern RfNbtx_Req *MF_rf_tx_level_req;
  96. extern CRFTXIQ*  MF_rf_txiq_ptr;
  97. // Tthread
  98. extern T_META_factory_calibration* pt_calibration;
  99. extern bool  is_suspend_cal; // in T_META_factory_calibration.cpp
  100. //---------------------------------------------------------------------------
  101. bool __fastcall T_META_factory_calibration::TXIqCal_EPSK( void )
  102. {
  103.     ViReal64  d_OOS[4];
  104.     ViReal64  d_POOS[4];
  105.     ViReal64  d_SBS[4];
  106.     ViReal64  d_PSBS[4];
  107.     ViReal64  d_OOS_min = 10000;
  108.     //ViReal64  d_SBS_min = 10000;
  109.     //S_IQ      s_trim_sbs_min;
  110.     S_IQ      s_offset_oos_min;
  111.     //RfBBTXCfg2   rf_bb_tx_cfg_req;
  112.     RfBBTXCfg4   rf_bb_tx_cfg_req;
  113.     BBTXParameters_T l1cal_txiq;
  114.     S_TXIQ_RESULT s_iq_result_low;
  115.     S_TXIQ_RESULT s_iq_result_high;
  116.     S_IQ OffsetIQ[] =
  117.     {
  118.         {  0,   0},
  119.         {  0,  30},
  120.         { 30, -30},
  121.         {-30, -30}
  122.     };
  123.     S_IQ TrimIQ[] =
  124.     {
  125.         {  0,   0},
  126.         {  7,  -7},
  127.         { -7,   7},
  128.         {  0,   0}
  129.     };
  130.     char c_TxPhasesel[] =
  131.     {
  132.         0,
  133.         0,
  134.         0,
  135.         3
  136.     };
  137.     PostMessage(ctrl.hPostMsgDestHandle,
  138.                 WM_MF_RF_TX_IQ_BEGIN,
  139.                 0,
  140.                 0
  141.                 );
  142.     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  143.              " ================ TX IQ calibration begin ================== "
  144.            );
  145.     if (!m_rct_ctrl.RCT_operatingMode(m_pRct, OPERATING_MODE_EGPRS_BCH_PDTCH))
  146.     {
  147.         CalErrorHandler(WM_MF_AGE8960_SET_OPERATION_MODE_FAIL);
  148.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  149.                               " FAIL :"+
  150.                               m_pRct->as_RCT + " < Operation mode = EGPRS BCH+PDTCH"
  151.                             );
  152.         return false;
  153.     }
  154.     m_viTX_IQ_BAND = Get_AgeBand(m_asTX_IQ_BAND);
  155.     E_BANDSEL band_index = AgeBand_To_BandIdx(m_viTX_IQ_BAND);
  156.     if (!m_rct_ctrl.RCT_cellBand(m_pRct, m_viTX_IQ_BAND))
  157.     {
  158.         CalErrorHandler(WM_MF_AGE8960_SET_BAND_FAIL);
  159.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  160.                               " FAIL : "+
  161.                               m_pRct->as_RCT + " < Band = " + ViBand_To_Str(m_viTX_IQ_BAND)
  162.                             );
  163.         return false;
  164.     }
  165.     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() + " " +
  166.                       m_pRct->as_RCT + " < Band = "+
  167.                       ViBand_To_Str(m_viTX_IQ_BAND)
  168.                     );
  169.     short bch_arfcn = ::Get_SeperateChannel(m_viTX_IQ_BAND, m_sTX_IQ_ARFCN);
  170.     if (!m_rct_ctrl.RCT_BCHARFCN(m_pRct, bch_arfcn))
  171.     {
  172.         CalErrorHandler(WM_MF_AGE8960_SET_TCH_ARFCN_FAIL);
  173.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  174.                               " FAIL :"+
  175.                               m_pRct->as_RCT + " < BCH ARFCN = " + IntToStr(bch_arfcn)
  176.                     );
  177.         return false;
  178.     }
  179.     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() + " " +
  180.                               m_pRct->as_RCT + " < BCH ARFCN = " + IntToStr(bch_arfcn)
  181.             );
  182.     if (!m_rct_ctrl.RCT_PDTCHARFCN(m_pRct, m_sTX_IQ_ARFCN))
  183.     {
  184.         CalErrorHandler(WM_MF_AGE8960_SET_PDTCH_ARFCN_FAIL);
  185.         log->Add( DateToStr(Date()) +  " " + CurrentTimeStr() +
  186.                               " FAIL : "+
  187.                               m_pRct->as_RCT + " < PDTCH ARFCN = " + IntToStr(m_sTX_IQ_ARFCN)
  188.                             );
  189.         return false;
  190.     }
  191.     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() + " " +
  192.                           m_pRct->as_RCT + " < PDTCH ARFCN = " + IntToStr( m_sTX_IQ_ARFCN )
  193.                         );
  194.     if (!m_rct_ctrl.RCT_PDTCHMSTxLevel(m_pRct, m_sTX_IQ_PCL))
  195.     {
  196.         CalErrorHandler(WM_MF_AGE8960_SET_MS_TX_LEVEL_FAIL);
  197.         log->Add( DateToStr(Date()) +  " " + CurrentTimeStr() +
  198.                                   " FAIL : " + m_pRct->as_RCT + " < MS TX level = " + IntToStr(m_sTX_IQ_PCL)
  199.                                 );
  200.         return false;
  201.     }
  202.     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() + " " +
  203.                       m_pRct->as_RCT + " < MS TX level = " + IntToStr(m_sTX_IQ_PCL)
  204.                      );
  205.     if (!m_rct_ctrl.RCT_ConfigTSC(m_pRct, m_cTSC))
  206.     {
  207.         CalErrorHandler(WM_MF_AGE8960_SET_TSC_FAIL);
  208.         log->Add( DateToStr(Date()) +  " " + CurrentTimeStr() +
  209.                               "FAIL : " + m_pRct->as_RCT + " < set TSC fail."
  210.                             );
  211.         return false;
  212.     }
  213.     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() + " " +
  214.                          m_pRct->as_RCT + " < TSC = " + IntToStr( m_cTSC)
  215.                       );
  216.     if (!m_rct_ctrl.RCT_Config_EPSK_CodingScheme(m_pRct, MCS5))
  217.     {
  218.         CalErrorHandler(WM_MF_AGE8960_SET_CODING_SCHEME_FAIL);
  219.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  220.                               " FAIL : " +
  221.                               m_pRct->as_RCT + " < Coding scheme = MCS5"
  222.                             );
  223.         return false;
  224.     }
  225.     if( ! m_rct_ctrl.RCT_Config_EPSK_ModACcuracy(m_pRct, m_uiTX_IQ_MEASUREMENT_COUNT, age1960_TRIG_AUTO, 0, 5) )
  226.     {
  227.          CalErrorHandler( WM_MF_AGE8960_CONFIG_EPSK_MOD_ACCURACY_FAIL );
  228.          log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  229.                               "FAIL : " + m_pRct->as_RCT + " < config EPSK modulation accurary fail."
  230.                             );
  231.          return false;
  232.     }
  233.     // read BB TX parameter from NVRAM
  234.     m_cTXIQ_RUN_Obj.ConfirmCallback = ::CNF_MF;
  235.     m_cTXIQ_RUN_Obj.REQ_GetBBTxCfg_Start(m_pCal->e_bbtxcfg_ver);
  236.     RestartTimerCal(WM_MF_RF_GET_BB_TX_CFG_FAIL);
  237.     SUSPEND_CAL_THREAD
  238.     if (m_cTXIQ_RUN_Obj.Get_ConfirmState() != METAAPP_SUCCESS)
  239.     {
  240.         CalErrorHandler(WM_MF_RF_GET_BB_TX_CFG_FAIL);
  241.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  242.                   " FAIL: Target > RF get BB TX CFG fail."
  243.                 );
  244.         return false;
  245.     }
  246.     RfBBTXCfg4* p_bbtx_cfg = m_cTXIQ_RUN_Obj.Get_BbTxCfg();
  247.     rf_bb_tx_cfg_req = *p_bbtx_cfg;
  248.     // read TXIQ from NVRAM
  249.     MF_rf_txiq_ptr->ConfirmCallback = ::ccb_read_txiq_from_nvram;
  250.     MF_rf_txiq_ptr->REQ_Read_From_NVRAM_Start(m_pCal->ui_rf_id, m_pCal->e_bbtxcfg_ver);
  251.     RestartTimerCal(WM_MF_NVRAM_TXIQ_READ_FAIL);
  252.     SUSPEND_CAL_THREAD
  253.     if (MF_rf_txiq_ptr->Get_ConfirmState() != METAAPP_SUCCESS)
  254.     {
  255.         CalErrorHandler(WM_MF_NVRAM_TXIQ_READ_FAIL);
  256.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  257.                                       " FAIL: Target > Read txiq value from NVRAM fail "
  258.                                      );
  259.         return false;
  260.     }
  261.     BBTXParameters_T* p_txiq = MF_rf_txiq_ptr->Get_BBTXParameters();
  262.     l1cal_txiq = *p_txiq;
  263.     l1cal_txiq.bbtx_gain                = rf_bb_tx_cfg_req.TxGain;
  264.     l1cal_txiq.bbtx_calrcsel            = rf_bb_tx_cfg_req.TxCalrcsel; // new
  265.     l1cal_txiq.bbtx_common_mode_voltage = rf_bb_tx_cfg_req.TxCMV; // new
  266.     // high band
  267.     l1cal_txiq.bbtx_gain_h                = rf_bb_tx_cfg_req.TxGain;
  268.     l1cal_txiq.bbtx_calrcsel_h            = rf_bb_tx_cfg_req.TxCalrcsel; // new
  269.     l1cal_txiq.bbtx_common_mode_voltage_h = rf_bb_tx_cfg_req.TxCMV; // new
  270.     for (int i=0; i<4; i++)
  271.     {
  272.         rf_bb_tx_cfg_req.TxTrimI    = TrimIQ[i].I;
  273.         rf_bb_tx_cfg_req.TxTrimQ    = TrimIQ[i].Q;
  274.         rf_bb_tx_cfg_req.TxOffsetI  = OffsetIQ[i].I;
  275.         rf_bb_tx_cfg_req.TxOffsetQ  = OffsetIQ[i].Q;
  276.         rf_bb_tx_cfg_req.TxPhasesel = c_TxPhasesel[i];
  277.         m_cTXIQ_RUN_Obj.ConfirmCallback = ::CNF_MF;
  278.         m_cTXIQ_RUN_Obj.REQ_SetBBTxCfg_Start(m_pCal->e_bbtxcfg_ver, rf_bb_tx_cfg_req);
  279.         RestartTimerCal(WM_MF_RF_SET_BB_TX_CFG_FAIL);
  280.         SUSPEND_CAL_THREAD
  281.         if (m_cTXIQ_RUN_Obj.Get_ConfirmState() != METAAPP_SUCCESS)
  282.         {
  283.             CalErrorHandler(WM_MF_RF_SET_BB_TX_CFG_FAIL);
  284.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  285.                   " FAIL: Target < RF set BB TX CFG fail."
  286.                 );
  287.             return false;
  288.         }
  289.         CHECK_TERMINATE_BY_USER
  290.         STOP_RF
  291.         Sleep(50);
  292.         int pcl[4];
  293.         CodingScheme cs[4];
  294.         APCTxPattern pattern;
  295.         cs[0]    = CodingSchemeMCS5;
  296.         cs[1]    = CodingSchemeMCS5;
  297.         cs[2]    = CodingSchemeMCS5;
  298.         cs[3]    = CodingSchemeMCS5;
  299.         pcl[0]   = m_sTX_IQ_PCL;
  300.         pcl[1]   = m_sTX_IQ_PCL;
  301.         pcl[2]   = m_sTX_IQ_PCL;
  302.         pcl[3]   = m_sTX_IQ_PCL;
  303.         pattern = NB_TX_RANDOM_WITH_TSC;
  304.         S_MULTI_SLOT_TX_T multi_slot_tx;
  305.         multi_slot_tx.b_MultiSlotTXExSupport = m_pCal->b_MultiSlotTxExSupport;
  306.         multi_slot_tx.e_bandsel = band_index;
  307.         multi_slot_tx.req.arfcn = m_sTX_IQ_ARFCN;
  308.         multi_slot_tx.req.bsic  = m_cTSC;
  309.         multi_slot_tx.req.timeSlotmask = 0x01;
  310.         for (int i=0; i<4; i++)
  311.         {
  312.             multi_slot_tx.req.powerLev[i] = pcl[i];
  313.     multi_slot_tx.req.cs[i]       = cs[i];
  314.         }
  315.         multi_slot_tx.req.ta = 0;
  316.         multi_slot_tx.req.frames = -99;
  317.         multi_slot_tx.req.dacValue = m_sDefault_value;
  318.         multi_slot_tx.req.pattern = pattern;
  319.         multi_slot_tx.req.pattern_data = 0;
  320.         RF_MULTI_SLOT_TX_Obj.ConfirmCallback   = ::ConfirmCallback_MultiSlotTX;
  321.         RF_MULTI_SLOT_TX_Obj.REQ_Start(multi_slot_tx);
  322.         SUSPEND_CAL_THREAD
  323.         if (RF_MULTI_SLOT_TX_Obj.Get_ConfirmState() != METAAPP_SUCCESS)
  324.         {
  325.             CalErrorHandler(WM_MF_RF_TX_LEVEL_FAIL);
  326.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  327.                           " FAIL: Target < multislot TX fail."
  328.                     );
  329.             return false;
  330.         }
  331.         // TX original offset & iq imbalance
  332.         if (!m_rct_ctrl.RCT_Fetch_EPSK_Average_TxIq(m_pRct, &d_SBS[i], &d_OOS[i]))
  333.         {
  334.             CalErrorHandler(WM_MF_AGE8960_FETCH_EPSK_OOS_FAIL);
  335.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  336.                       " FAIL : " + m_pRct->as_RCT + " > fetch EPSK original offset and IQ imbalance fail."
  337.                     );
  338.             return false;
  339.         }
  340.         d_PSBS[i] = exp(d_SBS[i]/10.0*logl(10.0));
  341.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  342.                       " TrimI = " + IntToStr( TrimIQ[i].I ) +
  343.                       ", TrimQ = " + IntToStr( TrimIQ[i].Q ) +
  344.                       ", SBS = " + Double_To_AnsiString( d_SBS[i] ) +
  345.                       ", PSBS = " + Double_To_AnsiString( d_PSBS[i] )
  346.                     );
  347.        // if (d_SBS_min > d_SBS[i])
  348.        // {
  349.        //     d_SBS_min = d_SBS[i];
  350.        //     s_trim_sbs_min.I = rf_bb_tx_cfg_req.TxTrimI;
  351.        //     s_trim_sbs_min.Q = rf_bb_tx_cfg_req.TxTrimQ;
  352.        //     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  353.        //              " TrimI = " + IntToStr(s_trim_sbs_min.I) +
  354.        //              ", TrimQ = " + IntToStr(s_trim_sbs_min.Q) +
  355.        //              ", min SBS = " + Double_To_AnsiString(d_SBS_min)
  356.        //             );
  357.        // }
  358.         if (NAN == d_OOS[i])
  359.         {
  360.             CalErrorHandler(WM_MF_RF_TX_IQ_FAIL);
  361.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  362.                       " FAIL :  Get TX original offset fail."
  363.                     );
  364.             return false;
  365.         }
  366.         d_POOS[i] = exp(d_OOS[i]/10.0*logl(10.0));
  367.         log->Add( DateToStr(Date()) +  " " + CurrentTimeStr() +
  368.                       " OffsetI = " + IntToStr( OffsetIQ[i].I ) +
  369.                       ", OffsetQ = " + IntToStr( OffsetIQ[i].Q ) +
  370.                       ", OOS = " + Double_To_AnsiString( d_OOS[i] ) +
  371.                       ", POOS = " + Double_To_AnsiString( d_POOS[i] )
  372.                     );
  373.         if (d_OOS_min > d_OOS[i])
  374.         {
  375.             d_OOS_min = d_OOS[i];
  376.             s_offset_oos_min.I = rf_bb_tx_cfg_req.TxOffsetI;
  377.             s_offset_oos_min.Q = rf_bb_tx_cfg_req.TxOffsetQ;
  378.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  379.                       " OffsetI = " + IntToStr(s_offset_oos_min.I) +
  380.                       ", OffsetQ = " + IntToStr(s_offset_oos_min.Q) +
  381.                       ", min OOS = " + Double_To_AnsiString(d_OOS_min)
  382.                     );
  383.         }
  384.         Sleep(50);
  385.         STOP_RF
  386.     }
  387.     S_IQ  offset_IQt;
  388.     S_IQ  trim_IQt;
  389.     char  c_TxPhasesel_eval;
  390.     // TX IQ gain imbalance
  391.     ViReal64 Xt;
  392.     Xt = 14*(d_PSBS[2]-d_PSBS[1]) / (2*(d_PSBS[2]+d_PSBS[1]-2*d_PSBS[0]));
  393.     float fdata = Xt/2.0;
  394.     fdata += (fdata>=0) ? 0.5 : -0.5 ;
  395.     trim_IQt.I = fdata;
  396.     fdata = -1.0*(Xt - trim_IQt.I);
  397.     fdata += (fdata>=0) ? 0.5 : -0.5 ;
  398.     trim_IQt.Q = fdata;
  399.     if (trim_IQt.I > MAX_TRIM_IQ)
  400.     {
  401.         trim_IQt.I = MAX_TRIM_IQ;
  402.     }
  403.     else if (trim_IQt.I < MIN_TRIM_IQ)
  404.     {
  405.         trim_IQt.I = MIN_TRIM_IQ;
  406.     }
  407.     if (trim_IQt.Q > MAX_TRIM_IQ)
  408.     {
  409.         trim_IQt.Q = MAX_TRIM_IQ;
  410.     }
  411.     else if (trim_IQt.Q < MIN_TRIM_IQ)
  412.     {
  413.         trim_IQt.Q = MIN_TRIM_IQ;
  414.     }
  415.     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  416.              " Evaluate Xt = " + Double_To_AnsiString(Xt) +
  417.              ", TrimI = " + IntToStr(trim_IQt.I) +
  418.              ", TrimQ = " + IntToStr(trim_IQt.Q)
  419.              );
  420.     // TX DC offset
  421.     fdata = 30*3*(d_POOS[3]-d_POOS[2]) / (2*(d_POOS[3]+d_POOS[2]+2*d_POOS[1]-4*d_POOS[0]));
  422.     fdata += (fdata>=0) ? 0.5 : -0.5 ;
  423.     offset_IQt.I = (int) fdata;
  424.     fdata= 30*(d_POOS[3]+d_POOS[2]-4*d_POOS[1]+2*d_POOS[0]) / (2*(d_POOS[3]+d_POOS[2]+2*d_POOS[1]-4*d_POOS[0]));
  425.     fdata += (fdata>=0) ? 0.5 : -0.5 ;
  426.     offset_IQt.Q = (int) fdata;
  427.     char MAX_OFFSET_IQ;
  428.     char MIN_OFFSET_IQ;
  429.     if (m_pCal->e_bbtxcfg_ver < BBTXCFG_VER4)
  430.     {
  431.         MIN_OFFSET_IQ = MIN_OFFSET_IQ_OLD;
  432.         MAX_OFFSET_IQ = MAX_OFFSET_IQ_OLD;
  433.     }
  434.     else
  435.     {
  436.         MIN_OFFSET_IQ = MIN_OFFSET_IQ_NEW;
  437.         MAX_OFFSET_IQ = MAX_OFFSET_IQ_NEW;
  438.     }
  439.     if (offset_IQt.I > MAX_OFFSET_IQ)
  440.     {
  441.         offset_IQt.I = MAX_OFFSET_IQ;
  442.     }
  443.     else if (offset_IQt.I < MIN_OFFSET_IQ)
  444.     {
  445.         offset_IQt.I = MIN_OFFSET_IQ;
  446.     }
  447.     if (offset_IQt.Q > MAX_OFFSET_IQ)
  448.     {
  449.         offset_IQt.Q = MAX_OFFSET_IQ;
  450.     }
  451.     else if (offset_IQt.Q < MIN_OFFSET_IQ)
  452.     {
  453.         offset_IQt.Q = MIN_OFFSET_IQ;
  454.     }
  455.     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  456.                       " Evaluate OffsetI = " + IntToStr( offset_IQt.I ) +
  457.                       ", OffsetQ = " + IntToStr( offset_IQt.Q )
  458.                     );
  459.     // Evaluate phasesel
  460.     double d_norm_phasesel = c_TxPhasesel[3] * 6.28 / 360.0;
  461.     fdata = ((pow(d_norm_phasesel, 2) + 4 * d_PSBS[0] - 4 * d_PSBS[3]) / (2 * d_norm_phasesel)) / 6.28 * 360.0;
  462.     fdata += (fdata>=0) ? 0.5 : -0.5 ;
  463.     c_TxPhasesel_eval = (char) fdata;
  464.     char c_max_phasesel;
  465.     char c_min_phasesel;
  466.     if (m_pCal->e_bbtxcfg_ver <= BBTXCFG_VER4)
  467.     {
  468.         c_min_phasesel = MIN_PHASESEL_OLD;
  469.         c_max_phasesel = MAX_PHASESEL_OLD;
  470.     }
  471.     else
  472.     {
  473.         c_min_phasesel = MIN_PHASESEL_NEW;
  474.         c_max_phasesel = MAX_PHASESEL_NEW;
  475.     }
  476.     if (c_TxPhasesel_eval > c_max_phasesel)
  477.     {
  478.         c_TxPhasesel_eval = c_max_phasesel;
  479.     }
  480.     else if (c_TxPhasesel_eval < c_min_phasesel)
  481.     {
  482.         c_TxPhasesel_eval = c_min_phasesel;
  483.     }
  484.     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  485.              " Evaluate Phasesel = " + IntToStr(c_TxPhasesel_eval)
  486.              );
  487.     l1cal_txiq.bbtx_trimI   = trim_IQt.I;
  488.     l1cal_txiq.bbtx_trimQ   = trim_IQt.Q;
  489.     l1cal_txiq.bbtx_offsetI = offset_IQt.I;
  490.     l1cal_txiq.bbtx_offsetQ = offset_IQt.Q;
  491.     l1cal_txiq.bbtx_phsel   = c_TxPhasesel_eval;
  492.     S_TXIQ txiq_low;
  493.     txiq_low.offset_IQ = offset_IQt;
  494.     txiq_low.trim_IQ   = trim_IQt;
  495.     txiq_low.c_TxPhasesel = c_TxPhasesel_eval;
  496.     if (!TXIqCheck_EPSK(true, 1, txiq_low, s_iq_result_low))
  497.     {
  498.         return false;
  499.     }
  500.     if (s_iq_result_low.b_oos_out_of_range)
  501.     {
  502.         OffsetIQ[0].I = offset_IQt.I;
  503.         OffsetIQ[0].Q = offset_IQt.Q;
  504.         OffsetIQ[1].I = offset_IQt.I;
  505.         OffsetIQ[1].Q = offset_IQt.Q + 5;
  506.         OffsetIQ[2].I = offset_IQt.I + 5;
  507.         OffsetIQ[2].Q = offset_IQt.Q - 5;
  508.         OffsetIQ[3].I = offset_IQt.I - 5;
  509.         OffsetIQ[3].Q = offset_IQt.Q - 5;
  510.         for (int i=0; i<4; i++)
  511.         {
  512.             if (OffsetIQ[i].I > MAX_OFFSET_IQ)
  513.             {
  514.                 OffsetIQ[i].I = MAX_OFFSET_IQ;
  515.             }
  516.             else if(OffsetIQ[i].I < MIN_OFFSET_IQ)
  517.             {
  518.                 OffsetIQ[i].I = MIN_OFFSET_IQ;
  519.             }
  520.             if (OffsetIQ[i].Q > MAX_OFFSET_IQ)
  521.             {
  522.                 OffsetIQ[i].Q = MAX_OFFSET_IQ;
  523.             }
  524.             else if(OffsetIQ[i].Q < MIN_OFFSET_IQ)
  525.             {
  526.                 OffsetIQ[i].Q = MIN_OFFSET_IQ;
  527.             }
  528.         }
  529.         for (int i=0; i<4; i++)
  530.         {
  531.             rf_bb_tx_cfg_req.TxOffsetI = OffsetIQ[i].I;
  532.             rf_bb_tx_cfg_req.TxOffsetQ = OffsetIQ[i].Q;
  533.             m_cTXIQ_RUN_Obj.ConfirmCallback = ::CNF_MF;
  534.             m_cTXIQ_RUN_Obj.REQ_SetBBTxCfg_Start(m_pCal->e_bbtxcfg_ver, rf_bb_tx_cfg_req);
  535.             RestartTimerCal(WM_MF_RF_SET_BB_TX_CFG_FAIL);
  536.             SUSPEND_CAL_THREAD
  537.             if (m_cTXIQ_RUN_Obj.Get_ConfirmState() != METAAPP_SUCCESS)
  538.             {
  539.                 CalErrorHandler(WM_MF_RF_SET_BB_TX_CFG_FAIL);
  540.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  541.                          " FAIL: Target < RF set BB TX CFG fail."
  542.                         );
  543.                 return false;
  544.             }
  545.             CHECK_TERMINATE_BY_USER
  546.             STOP_RF
  547.             Sleep(50);
  548.             int   pcl[4];
  549.             CodingScheme cs[4];
  550.             APCTxPattern pattern;
  551.             cs[0]    = CodingSchemeMCS5;
  552.             cs[1]    = CodingSchemeMCS5;
  553.             cs[2]    = CodingSchemeMCS5;
  554.             cs[3]    = CodingSchemeMCS5;
  555.             pcl[0]   = m_sTX_IQ_PCL;
  556.             pcl[1]   = m_sTX_IQ_PCL;
  557.             pcl[2]   = m_sTX_IQ_PCL;
  558.             pcl[3]   = m_sTX_IQ_PCL;
  559.             pattern = NB_TX_RANDOM_WITH_TSC;
  560.             S_MULTI_SLOT_TX_T multi_slot_tx;
  561.             multi_slot_tx.b_MultiSlotTXExSupport = m_pCal->b_MultiSlotTxExSupport;
  562.             multi_slot_tx.e_bandsel = band_index;
  563.             multi_slot_tx.req.arfcn = m_sTX_IQ_ARFCN;
  564.             multi_slot_tx.req.bsic  = m_cTSC;
  565.             multi_slot_tx.req.timeSlotmask = 0x01;
  566.             for (int i=0; i<4; i++)
  567.             {
  568.                 multi_slot_tx.req.powerLev[i] = pcl[i];
  569.         multi_slot_tx.req.cs[i]       = cs[i];
  570.             }
  571.             multi_slot_tx.req.ta = 0;
  572.             multi_slot_tx.req.frames = -99;
  573.             multi_slot_tx.req.dacValue = m_sDefault_value;
  574.             multi_slot_tx.req.pattern = pattern;
  575.             multi_slot_tx.req.pattern_data = 0;
  576.             RF_MULTI_SLOT_TX_Obj.ConfirmCallback   = ::ConfirmCallback_MultiSlotTX;
  577.             RF_MULTI_SLOT_TX_Obj.REQ_Start(multi_slot_tx);
  578.             SUSPEND_CAL_THREAD
  579.             if (RF_MULTI_SLOT_TX_Obj.Get_ConfirmState() != METAAPP_SUCCESS)
  580.             {
  581.                 CalErrorHandler(WM_MF_RF_TX_LEVEL_FAIL);
  582.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  583.                           " FAIL: Target < multislot TX fail."
  584.                         );
  585.                 return false;
  586.             }
  587.             // TX DC offset & IQ imbalance
  588.             if (!m_rct_ctrl.RCT_Fetch_EPSK_Average_OrignalOffset( m_pRct, &d_OOS[i]))
  589.             {
  590.                 CalErrorHandler(WM_MF_AGE8960_FETCH_EPSK_OOS_FAIL);
  591.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  592.                              " FAIL : " + m_pRct->as_RCT + " > fetch EPSK original offset fail."
  593.                             );
  594.                 return false;
  595.             }
  596.             if (NAN == d_OOS[i])
  597.             {
  598.                 CalErrorHandler(WM_MF_RF_TX_IQ_FAIL);
  599.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  600.                              " FAIL :  Get TX original offset fail."
  601.                             );
  602.                 return false;
  603.             }
  604.             d_POOS[i] = exp(d_OOS[i]/10.0*logl(10.0));
  605.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  606.                      " OffsetI = " + IntToStr( OffsetIQ[i].I ) +
  607.                      ", OffsetQ = " + IntToStr( OffsetIQ[i].Q ) +
  608.                      ", OOS = " + Double_To_AnsiString( d_OOS[i] ) +
  609.                      ", POOS = " + Double_To_AnsiString( d_POOS[i] )
  610.                      );
  611.             if (d_OOS_min > d_OOS[i])
  612.             {
  613.                 d_OOS_min = d_OOS[i];
  614.                 s_offset_oos_min.I = rf_bb_tx_cfg_req.TxOffsetI;
  615.                 s_offset_oos_min.Q = rf_bb_tx_cfg_req.TxOffsetQ;
  616.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  617.                              " OffsetI = " + IntToStr(s_offset_oos_min.I) +
  618.                              ", OffsetQ = " + IntToStr(s_offset_oos_min.Q) +
  619.                              ", min OOS = " + Double_To_AnsiString(d_OOS_min)
  620.                             );
  621.             }
  622.             STOP_RF
  623.         }
  624.         // TX DC offset
  625.         fdata = 5*3*(d_POOS[3]-d_POOS[2]) / (2*(d_POOS[3]+d_POOS[2]+2*d_POOS[1]-4*d_POOS[0])) + offset_IQt.I;
  626.         fdata += (fdata>=0) ? 0.5 : -0.5 ;
  627.         offset_IQt.I = fdata;
  628.         fdata= 5*(d_POOS[3]+d_POOS[2]-4*d_POOS[1]+2*d_POOS[0]) / (2*(d_POOS[3]+d_POOS[2]+2*d_POOS[1]-4*d_POOS[0])) + offset_IQt.Q;
  629.         fdata += (fdata>=0) ? 0.5 : -0.5 ;
  630.         offset_IQt.Q = fdata;
  631.         if (offset_IQt.I > MAX_OFFSET_IQ)
  632.         {
  633.             offset_IQt.I = MAX_OFFSET_IQ;
  634.         }
  635.         else if(offset_IQt.I < MIN_OFFSET_IQ)
  636.         {
  637.             offset_IQt.I = MIN_OFFSET_IQ;
  638.         }
  639.         if (offset_IQt.Q > MAX_OFFSET_IQ)
  640.         {
  641.             offset_IQt.Q = MAX_OFFSET_IQ;
  642.         }
  643.         else if(offset_IQt.Q < MIN_OFFSET_IQ)
  644.         {
  645.             offset_IQt.Q = MIN_OFFSET_IQ;
  646.         }
  647.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  648.                       " Evaluate OffsetI = " + IntToStr( offset_IQt.I ) +
  649.                       ", OffsetQ = " + IntToStr( offset_IQt.Q )
  650.                     );
  651.         S_TXIQ txiq_low;
  652.         txiq_low.offset_IQ = offset_IQt;
  653.         txiq_low.trim_IQ   = trim_IQt;
  654.         txiq_low.c_TxPhasesel = c_TxPhasesel_eval;
  655.         if (!TXIqCheck_EPSK(true, 2, txiq_low, s_iq_result_low))
  656.         {
  657.             return false;
  658.         }
  659.     }
  660.    // if (d_SBS_min > s_iq_result_low.d_sbs)
  661.    // {
  662.    //     d_SBS_min = s_iq_result_low.d_sbs;
  663.    //     s_trim_sbs_min = txiq_low.trim_IQ;
  664.    //     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  665.    //              " TrimI = " + IntToStr(s_trim_sbs_min.I) +
  666.    //              ", TrimQ = " + IntToStr(s_trim_sbs_min.Q) +
  667.    //              ", min SBS = " + Double_To_AnsiString(d_SBS_min)
  668.    //             );
  669.    //
  670.    // }
  671.     if (d_OOS_min > s_iq_result_low.d_oos)
  672.     {
  673.         d_OOS_min = s_iq_result_low.d_oos;
  674.         s_offset_oos_min = txiq_low.offset_IQ;
  675.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  676.                  " OffsetI = " + IntToStr(s_offset_oos_min.I) +
  677.                  ", OffsetQ = " + IntToStr(s_offset_oos_min.Q) +
  678.                  ", min OOS = " + Double_To_AnsiString(d_OOS_min)
  679.                 );
  680.     }
  681.     l1cal_txiq.bbtx_trimI   = trim_IQt.I;
  682.     l1cal_txiq.bbtx_trimQ   = trim_IQt.Q;
  683.     l1cal_txiq.bbtx_offsetI = s_offset_oos_min.I;
  684.     l1cal_txiq.bbtx_offsetQ = s_offset_oos_min.Q;
  685.     l1cal_txiq.bbtx_phsel   = c_TxPhasesel_eval;
  686.     // high band calibration
  687.     if ((RF_ID_A60111A == m_pCal->ui_rf_id) ||
  688.         (RF_ID_AERO2E  == m_pCal->ui_rf_id) ||
  689.         (RF_ID_MT6140A == m_pCal->ui_rf_id) ||
  690.         (RF_ID_MT6140B == m_pCal->ui_rf_id) ||
  691.         (RF_ID_MT6140C == m_pCal->ui_rf_id) ||
  692.         (RF_ID_MT6140D == m_pCal->ui_rf_id)
  693.        )
  694.     {
  695.          OffsetIQ[0].I = 0;
  696.          OffsetIQ[0].Q = 0;
  697.          OffsetIQ[1].I = 0;
  698.          OffsetIQ[1].Q = 30;
  699.          OffsetIQ[2].I = 30;
  700.          OffsetIQ[2].Q = -30;
  701.          OffsetIQ[3].I = -30;
  702.          OffsetIQ[3].Q = -30;
  703.         m_viTX_IQ_BAND_HIGH = Get_AgeBand(m_asTX_IQ_BAND_HIGH);
  704.         band_index = AgeBand_To_BandIdx(m_viTX_IQ_BAND_HIGH);
  705.         if (!m_rct_ctrl.RCT_cellBand(m_pRct, m_viTX_IQ_BAND_HIGH))
  706.         {
  707.             CalErrorHandler(WM_MF_AGE8960_SET_BAND_FAIL);
  708.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  709.                      " FAIL : "+
  710.                      m_pRct->as_RCT + " < Band = " + ViBand_To_Str(m_viTX_IQ_BAND_HIGH)
  711.                     );
  712.             return false;
  713.         }
  714.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() + " " +
  715.                  m_pRct->as_RCT + " < Band = "+
  716.                  ViBand_To_Str( m_viTX_IQ_BAND_HIGH )
  717.                  );
  718.         short bch_arfcn = ::Get_SeperateChannel(m_viTX_IQ_BAND_HIGH, m_sTX_IQ_ARFCN_HIGH);
  719.         if (!m_rct_ctrl.RCT_BCHARFCN(m_pRct, bch_arfcn))
  720.         {
  721.             CalErrorHandler(WM_MF_AGE8960_SET_TCH_ARFCN_FAIL);
  722.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  723.                      " FAIL : " +
  724.                      m_pRct->as_RCT + " < BCH ARFCN = " + IntToStr(bch_arfcn)
  725.                     );
  726.             return false;
  727.         }
  728.         if (!m_rct_ctrl.RCT_PDTCHARFCN(m_pRct, m_sTX_IQ_ARFCN_HIGH))
  729.         {
  730.             CalErrorHandler(WM_MF_AGE8960_SET_PDTCH_ARFCN_FAIL);
  731.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  732.                      " FAIL : " +
  733.                      m_pRct->as_RCT + " < PDTCH ARFCN = " + IntToStr(m_sTX_IQ_ARFCN_HIGH)
  734.                      );
  735.             return false;
  736.         }
  737.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() + " " +
  738.                  m_pRct->as_RCT + " < PDTCH ARFCN = " + IntToStr(m_sTX_IQ_ARFCN_HIGH)
  739.                  );
  740.         if (!m_rct_ctrl.RCT_PDTCHMSTxLevel(m_pRct, m_sTX_IQ_PCL_HIGH))
  741.         {
  742.             CalErrorHandler(WM_MF_AGE8960_SET_MS_TX_LEVEL_FAIL);
  743.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  744.                      " FAIL : " + m_pRct->as_RCT + " < MS TX level = " + IntToStr(m_sTX_IQ_PCL_HIGH)
  745.                     );
  746.             return false;
  747.         }
  748.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() + " " +
  749.                  m_pRct->as_RCT + " < MS TX level = " + IntToStr(m_sTX_IQ_PCL_HIGH)
  750.                  );
  751.         if (!m_rct_ctrl.RCT_ConfigTSC(m_pRct, m_cTSC))
  752.         {
  753.             CalErrorHandler(WM_MF_AGE8960_SET_TSC_FAIL);
  754.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  755.                      "FAIL : " + m_pRct->as_RCT + " < set TSC fail."
  756.                      );
  757.             return false;
  758.         }
  759.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() + " " +
  760.                  m_pRct->as_RCT + " < TSC = " + IntToStr(m_cTSC)
  761.                  );
  762.         if (!m_rct_ctrl.RCT_Config_EPSK_ModACcuracy(m_pRct, m_uiTX_IQ_MEASUREMENT_COUNT, age1960_TRIG_AUTO, 0, 5))
  763.         {
  764.             CalErrorHandler(WM_MF_AGE8960_CONFIG_IQ_TUNNING_FAIL);
  765.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  766.                               "FAIL : " + m_pRct->as_RCT + " < config EPSK modulation accurary fail."
  767.                             );
  768.             return false;
  769.         }
  770.         for (int i=0; i<4; i++)
  771.         {
  772.             rf_bb_tx_cfg_req.TxTrimI    = TrimIQ[i].I;
  773.             rf_bb_tx_cfg_req.TxTrimQ    = TrimIQ[i].Q;
  774.             rf_bb_tx_cfg_req.TxOffsetI  = OffsetIQ[i].I;
  775.             rf_bb_tx_cfg_req.TxOffsetQ  = OffsetIQ[i].Q;
  776.             rf_bb_tx_cfg_req.TxPhasesel = c_TxPhasesel[i];
  777.             m_cTXIQ_RUN_Obj.ConfirmCallback = ::CNF_MF;
  778.             m_cTXIQ_RUN_Obj.REQ_SetBBTxCfg_Start(m_pCal->e_bbtxcfg_ver, rf_bb_tx_cfg_req);
  779.             RestartTimerCal(WM_MF_RF_SET_BB_TX_CFG_FAIL);
  780.             SUSPEND_CAL_THREAD
  781.             if (m_cTXIQ_RUN_Obj.Get_ConfirmState() != METAAPP_SUCCESS)
  782.             {
  783.                 CalErrorHandler(WM_MF_RF_SET_BB_TX_CFG_FAIL);
  784.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  785.                          " FAIL: Target < RF set BB TX CFG fail."
  786.                         );
  787.                 return false;
  788.             }
  789.             CHECK_TERMINATE_BY_USER
  790.             STOP_RF
  791.             Sleep(50);
  792.             int   pcl[4];
  793.             CodingScheme cs[4];
  794.             APCTxPattern pattern;
  795.             cs[0]    = CodingSchemeMCS5;
  796.             cs[1]    = CodingSchemeMCS5;
  797.             cs[2]    = CodingSchemeMCS5;
  798.             cs[3]    = CodingSchemeMCS5;
  799.             pcl[0]   = m_sTX_IQ_PCL_HIGH;
  800.             pcl[1]   = m_sTX_IQ_PCL_HIGH;
  801.             pcl[2]   = m_sTX_IQ_PCL_HIGH;
  802.             pcl[3]   = m_sTX_IQ_PCL_HIGH;
  803.             pattern = NB_TX_RANDOM_WITH_TSC;
  804.             S_MULTI_SLOT_TX_T multi_slot_tx;
  805.             multi_slot_tx.b_MultiSlotTXExSupport = m_pCal->b_MultiSlotTxExSupport;
  806.             multi_slot_tx.e_bandsel = band_index;
  807.             multi_slot_tx.req.arfcn = m_sTX_IQ_ARFCN_HIGH;
  808.             multi_slot_tx.req.bsic  = m_cTSC;
  809.             multi_slot_tx.req.timeSlotmask = 0x01;
  810.             for (int i=0; i<4; i++)
  811.             {
  812.                 multi_slot_tx.req.powerLev[i] = pcl[i];
  813.         multi_slot_tx.req.cs[i]       = cs[i];
  814.             }
  815.             multi_slot_tx.req.ta = 0;
  816.             multi_slot_tx.req.frames = -99;
  817.             multi_slot_tx.req.dacValue = m_sDefault_value;
  818.             multi_slot_tx.req.pattern = pattern;
  819.             multi_slot_tx.req.pattern_data = 0;
  820.             RF_MULTI_SLOT_TX_Obj.ConfirmCallback   = ::ConfirmCallback_MultiSlotTX;
  821.             RF_MULTI_SLOT_TX_Obj.REQ_Start(multi_slot_tx);
  822.             SUSPEND_CAL_THREAD
  823.             if (RF_MULTI_SLOT_TX_Obj.Get_ConfirmState() != METAAPP_SUCCESS)
  824.             {
  825.                 CalErrorHandler(WM_MF_RF_TX_LEVEL_FAIL);
  826.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  827.                           " FAIL: Target < multislot TX fail."
  828.                         );
  829.                 return false;
  830.             }
  831.             // TX DC offset & IQ imbalance
  832.             if (!m_rct_ctrl.RCT_Fetch_EPSK_Average_TxIq(m_pRct, &d_SBS[i], &d_OOS[i]))
  833.             {
  834.                     CalErrorHandler(WM_MF_AGE8960_FETCH_EPSK_OOS_FAIL);
  835.                     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  836.                                   " FAIL : " + m_pRct->as_RCT + " > fetch EPSK original offset and IQ imbalance fail."
  837.                                 );
  838.                     return false;
  839.             }
  840.             if (NAN == d_SBS[i])
  841.             {
  842.                 CalErrorHandler(WM_MF_RF_TX_IQ_FAIL);
  843.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  844.                          " FAIL :  Get TX IQ imbalance fail."
  845.                         );
  846.                 return false;
  847.             }
  848.             d_PSBS[i] = exp(d_SBS[i]/10.0*logl(10.0));
  849.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  850.                      " TrimI = " + IntToStr( TrimIQ[i].I ) +
  851.                      ", TrimQ = " + IntToStr( TrimIQ[i].Q ) +
  852.                      ", SBS = " + Double_To_AnsiString( d_SBS[i] ) +
  853.                      ", PSBS = " + Double_To_AnsiString( d_PSBS[i] )
  854.                     );
  855.           //  if (d_SBS_min >d_SBS[i])
  856.           //  {
  857.           //      d_SBS_min = d_SBS[i];
  858.           //      s_trim_sbs_min.I = rf_bb_tx_cfg_req.TxTrimI;
  859.           //      s_trim_sbs_min.Q = rf_bb_tx_cfg_req.TxTrimQ;
  860.           //      log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  861.           //               " TrimI = " + IntToStr(s_trim_sbs_min.I) +
  862.           //               ", TrimQ = " + IntToStr(s_trim_sbs_min.Q) +
  863.           //               ", min SBS = " + Double_To_AnsiString(d_SBS_min)
  864.           //               );
  865.           //  }
  866.             if( NAN == d_OOS[i] )
  867.             {
  868.                 CalErrorHandler( WM_MF_RF_TX_IQ_FAIL );
  869.                 log->Add( DateToStr(Date()) +  " " + CurrentTimeStr() +
  870.                                " FAIL :  Get TX original offset fail."
  871.                             );
  872.                 return false;
  873.             }
  874.             d_POOS[i] = exp(d_OOS[i]/10.0*logl(10.0));
  875.             log->Add( DateToStr(Date()) +  " " + CurrentTimeStr() +
  876.                       " OffsetI = " + IntToStr( OffsetIQ[i].I ) +
  877.                       ", OffsetQ = " + IntToStr( OffsetIQ[i].Q ) +
  878.                       ", OOS = " + Double_To_AnsiString( d_OOS[i] ) +
  879.                       ", POOS = " + Double_To_AnsiString( d_POOS[i] )
  880.                     );
  881.             if (d_OOS_min > d_OOS[i])
  882.             {
  883.                     d_OOS_min = d_OOS[i];
  884.                     s_offset_oos_min.I = rf_bb_tx_cfg_req.TxOffsetI;
  885.                     s_offset_oos_min.Q = rf_bb_tx_cfg_req.TxOffsetQ;
  886.                     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  887.                              " OffsetI = " + IntToStr(s_offset_oos_min.I) +
  888.                              ", OffsetQ = " + IntToStr(s_offset_oos_min.Q) +
  889.                              ", min OOS = " + Double_To_AnsiString(d_OOS_min)
  890.                             );
  891.             }
  892.             STOP_RF
  893.         }
  894.         S_IQ offset_IQt_h;
  895.         S_IQ trim_IQt_h;
  896.         char c_TxPhasesel_eval_h;
  897.         // TX IQ gain imbalance
  898.         ViReal64 Xt;
  899.         Xt = 14*(d_PSBS[2]-d_PSBS[1]) / (2*(d_PSBS[2]+d_PSBS[1]-2*d_PSBS[0]));
  900.         float fdata = Xt/2.0;
  901.         fdata += (fdata>=0) ? 0.5 : -0.5 ;
  902.         trim_IQt_h.I = fdata;
  903.         fdata = -1.0*(Xt - trim_IQt_h.I);
  904.         fdata += (fdata>=0) ? 0.5 : -0.5 ;
  905.         trim_IQt_h.Q = fdata;
  906.         if (trim_IQt_h.I > MAX_TRIM_IQ)
  907.         {
  908.             trim_IQt_h.I = MAX_TRIM_IQ;
  909.         }
  910.         else if(trim_IQt_h.I < MIN_TRIM_IQ)
  911.         {
  912.             trim_IQt_h.I = MIN_TRIM_IQ;
  913.         }
  914.         if (trim_IQt_h.Q > MAX_TRIM_IQ)
  915.         {
  916.             trim_IQt_h.Q = MAX_TRIM_IQ;
  917.         }
  918.         else if(trim_IQt_h.Q < MIN_TRIM_IQ)
  919.         {
  920.             trim_IQt_h.Q = MIN_TRIM_IQ;
  921.         }
  922.         log->Add( DateToStr(Date()) +  " " + CurrentTimeStr() +
  923.                       " Evaluate Xt = " + Double_To_AnsiString(Xt) + ", TrimI = " + IntToStr( trim_IQt_h.I ) +
  924.                       ", TrimQ = " + IntToStr( trim_IQt_h.Q )
  925.                     );
  926.         // TX DC offset
  927.         fdata = 30*3*(d_POOS[3]-d_POOS[2]) / (2*(d_POOS[3]+d_POOS[2]+2*d_POOS[1]-4*d_POOS[0]));
  928.         fdata += (fdata>=0) ? 0.5 : -0.5 ;
  929.         offset_IQt_h.I = fdata;
  930.         fdata= 30*(d_POOS[3]+d_POOS[2]-4*d_POOS[1]+2*d_POOS[0]) / (2*(d_POOS[3]+d_POOS[2]+2*d_POOS[1]-4*d_POOS[0]));
  931.         fdata += (fdata>=0) ? 0.5 : -0.5 ;
  932.         offset_IQt_h.Q = fdata;
  933.         if (offset_IQt_h.I > MAX_OFFSET_IQ)
  934.         {
  935.             offset_IQt_h.I = MAX_OFFSET_IQ;
  936.         }
  937.         else if(offset_IQt_h.I < MIN_OFFSET_IQ)
  938.         {
  939.             offset_IQt_h.I = MIN_OFFSET_IQ;
  940.         }
  941.         if (offset_IQt_h.Q > MAX_OFFSET_IQ)
  942.         {
  943.             offset_IQt_h.Q = MAX_OFFSET_IQ;
  944.         }
  945.         else if(offset_IQt_h.Q < MIN_OFFSET_IQ)
  946.         {
  947.             offset_IQt_h.Q = MIN_OFFSET_IQ;
  948.         }
  949.         log->Add( DateToStr(Date()) +  " " + CurrentTimeStr() +
  950.                       " Evaluate OffsetI = " + IntToStr( offset_IQt_h.I ) +
  951.                       ", OffsetQ = " + IntToStr( offset_IQt_h.Q )
  952.                     );
  953.         // Evaluate phasesel
  954.         double d_norm_phasesel_h = c_TxPhasesel[3] * 6.28 / 360.0;
  955.         fdata = ((pow(d_norm_phasesel_h, 2) + 4 * d_PSBS[0] - 4 * d_PSBS[3]) / (2 * d_norm_phasesel_h)) / 6.28 * 360.0;
  956.         fdata += (fdata>=0) ? 0.5 : -0.5 ;
  957.         c_TxPhasesel_eval_h = (char) fdata;
  958.         if (c_TxPhasesel_eval_h > c_max_phasesel)
  959.         {
  960.             c_TxPhasesel_eval_h = c_max_phasesel;
  961.         }
  962.         else if (c_TxPhasesel_eval_h < c_min_phasesel)
  963.         {
  964.             c_TxPhasesel_eval_h = c_min_phasesel;
  965.         }
  966.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  967.              " Evaluate Phasesel = " + IntToStr(c_TxPhasesel_eval_h)
  968.              );
  969.         l1cal_txiq.bbtx_trimI_h   = trim_IQt_h.I;
  970.         l1cal_txiq.bbtx_trimQ_h   = trim_IQt_h.Q;
  971.         l1cal_txiq.bbtx_offsetI_h = offset_IQt_h.I;
  972.         l1cal_txiq.bbtx_offsetQ_h = offset_IQt_h.Q;
  973.         l1cal_txiq.bbtx_phsel_h   = c_TxPhasesel_eval_h;
  974.         S_TXIQ txiq_high;
  975.         txiq_high.offset_IQ = offset_IQt_h;
  976.         txiq_high.trim_IQ   = trim_IQt_h;
  977.         txiq_high.c_TxPhasesel = c_TxPhasesel_eval_h;
  978.         if (!TXIqCheck_EPSK(false, 1, txiq_high, s_iq_result_high))
  979.         {
  980.             return false;
  981.         }
  982.         if (s_iq_result_high.b_oos_out_of_range)
  983.         {
  984.             OffsetIQ[0].I = offset_IQt_h.I;
  985.             OffsetIQ[0].Q = offset_IQt_h.Q;
  986.             OffsetIQ[1].I = offset_IQt_h.I;
  987.             OffsetIQ[1].Q = offset_IQt_h.Q + 5;
  988.             OffsetIQ[2].I = offset_IQt_h.I + 5;
  989.             OffsetIQ[2].Q = offset_IQt_h.Q - 5;
  990.             OffsetIQ[3].I = offset_IQt_h.I - 5;
  991.             OffsetIQ[3].Q = offset_IQt_h.Q - 5;
  992.             for (int i=0; i<4; i++)
  993.             {
  994.                 if (OffsetIQ[i].I > MAX_OFFSET_IQ)
  995.                 {
  996.                     OffsetIQ[i].I = MAX_OFFSET_IQ;
  997.                 }
  998.                 else if(OffsetIQ[i].I < MIN_OFFSET_IQ)
  999.                 {
  1000.                     OffsetIQ[i].I = MIN_OFFSET_IQ;
  1001.                 }
  1002.                 if (OffsetIQ[i].Q > MAX_OFFSET_IQ)
  1003.                 {
  1004.                     OffsetIQ[i].Q = MAX_OFFSET_IQ;
  1005.                 }
  1006.                 else if(OffsetIQ[i].Q < MIN_OFFSET_IQ)
  1007.                 {
  1008.                     OffsetIQ[i].Q = MIN_OFFSET_IQ;
  1009.                 }
  1010.             }
  1011.             for (int i=0; i<4; i++)
  1012.             {
  1013.                 rf_bb_tx_cfg_req.TxOffsetI = OffsetIQ[i].I;
  1014.                 rf_bb_tx_cfg_req.TxOffsetQ = OffsetIQ[i].Q;
  1015.                 m_cTXIQ_RUN_Obj.ConfirmCallback = ::CNF_MF;
  1016.                 m_cTXIQ_RUN_Obj.REQ_SetBBTxCfg_Start(m_pCal->e_bbtxcfg_ver, rf_bb_tx_cfg_req);
  1017.                 RestartTimerCal(WM_MF_RF_SET_BB_TX_CFG_FAIL);
  1018.                 SUSPEND_CAL_THREAD
  1019.                 if (m_cTXIQ_RUN_Obj.Get_ConfirmState() != METAAPP_SUCCESS)
  1020.                 {
  1021.                     CalErrorHandler(WM_MF_RF_SET_BB_TX_CFG_FAIL);
  1022.                     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1023.                              " FAIL: Target < RF set BB TX CFG fail."
  1024.                              );
  1025.                     return false;
  1026.                 }
  1027.                 CHECK_TERMINATE_BY_USER
  1028.                 STOP_RF
  1029.                 Sleep(50);
  1030.                 int   pcl[4];
  1031.                 CodingScheme cs[4];
  1032.                 APCTxPattern pattern;
  1033.                 cs[0]    = CodingSchemeMCS5;
  1034.                 cs[1]    = CodingSchemeMCS5;
  1035.                 cs[2]    = CodingSchemeMCS5;
  1036.                 cs[3]    = CodingSchemeMCS5;
  1037.                 pcl[0]   = m_sTX_IQ_PCL_HIGH;
  1038.                 pcl[1]   = m_sTX_IQ_PCL_HIGH;
  1039.                 pcl[2]   = m_sTX_IQ_PCL_HIGH;
  1040.                 pcl[3]   = m_sTX_IQ_PCL_HIGH;
  1041.                 pattern = NB_TX_RANDOM_WITH_TSC;
  1042.                 S_MULTI_SLOT_TX_T multi_slot_tx;
  1043.                 multi_slot_tx.b_MultiSlotTXExSupport = m_pCal->b_MultiSlotTxExSupport;
  1044.                 multi_slot_tx.e_bandsel = band_index;
  1045.                 multi_slot_tx.req.arfcn = m_sTX_IQ_ARFCN_HIGH;
  1046.                 multi_slot_tx.req.bsic  = m_cTSC;
  1047.                 multi_slot_tx.req.timeSlotmask = 0x01;
  1048.                 for (int i=0; i<4; i++)
  1049.                 {
  1050.                     multi_slot_tx.req.powerLev[i] = pcl[i];
  1051.             multi_slot_tx.req.cs[i]       = cs[i];
  1052.                 }
  1053.                 multi_slot_tx.req.ta = 0;
  1054.                 multi_slot_tx.req.frames = -99;
  1055.                 multi_slot_tx.req.dacValue = m_sDefault_value;
  1056.                 multi_slot_tx.req.pattern = pattern;
  1057.                 multi_slot_tx.req.pattern_data = 0;
  1058.                 RF_MULTI_SLOT_TX_Obj.ConfirmCallback   = ::ConfirmCallback_MultiSlotTX;
  1059.                 RF_MULTI_SLOT_TX_Obj.REQ_Start(multi_slot_tx);
  1060.                 SUSPEND_CAL_THREAD
  1061.                 if (RF_MULTI_SLOT_TX_Obj.Get_ConfirmState() != METAAPP_SUCCESS)
  1062.                 {
  1063.                     CalErrorHandler(WM_MF_RF_TX_LEVEL_FAIL);
  1064.                     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1065.                           " FAIL: Target < multislot TX fail."
  1066.                         );
  1067.                     return false;
  1068.                 }
  1069.                 // TX DC offset
  1070.                 if (!m_rct_ctrl.RCT_Fetch_EPSK_Average_OrignalOffset(m_pRct, &d_OOS[i]))
  1071.                 {
  1072.                     CalErrorHandler(WM_MF_AGE8960_FETCH_EPSK_OOS_FAIL);
  1073.                     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1074.                                   " FAIL : " + m_pRct->as_RCT + " > fetch EPSK original offset fail."
  1075.                                 );
  1076.                     return false;
  1077.                 }
  1078.                 if (NAN == d_OOS[i])
  1079.                 {
  1080.                     CalErrorHandler(WM_MF_RF_TX_IQ_FAIL);
  1081.                     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1082.                              " FAIL :  Get TX original offset fail."
  1083.                             );
  1084.                     return false;
  1085.                 }
  1086.                 d_POOS[i] = exp(d_OOS[i]/10.0*logl(10.0));
  1087.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1088.                          " OffsetI = " + IntToStr( OffsetIQ[i].I ) +
  1089.                          ", OffsetQ = " + IntToStr( OffsetIQ[i].Q ) +
  1090.                          ", OOS = " + Double_To_AnsiString( d_OOS[i] ) +
  1091.                          ", POOS = " + Double_To_AnsiString( d_POOS[i] )
  1092.                         );
  1093.                 if (d_OOS_min > d_OOS[i])
  1094.                 {
  1095.                     d_OOS_min = d_OOS[i];
  1096.                     s_offset_oos_min.I = rf_bb_tx_cfg_req.TxOffsetI;
  1097.                     s_offset_oos_min.Q = rf_bb_tx_cfg_req.TxOffsetQ;
  1098.                     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1099.                              " OffsetI = " + IntToStr(s_offset_oos_min.I) +
  1100.                              ", OffsetQ = " + IntToStr(s_offset_oos_min.Q) +
  1101.                              ", min OOS = " + Double_To_AnsiString(d_OOS_min)
  1102.                             );
  1103.                 }
  1104.                 STOP_RF
  1105.             }
  1106.             // TX DC offset
  1107.             fdata = 5*3*(d_POOS[3]-d_POOS[2]) / (2*(d_POOS[3]+d_POOS[2]+2*d_POOS[1]-4*d_POOS[0])) + offset_IQt_h.I;
  1108.             fdata += (fdata>=0) ? 0.5 : -0.5 ;
  1109.             offset_IQt_h.I = fdata;
  1110.             fdata= 5*(d_POOS[3]+d_POOS[2]-4*d_POOS[1]+2*d_POOS[0]) / (2*(d_POOS[3]+d_POOS[2]+2*d_POOS[1]-4*d_POOS[0])) + offset_IQt_h.Q;
  1111.             fdata += (fdata>=0) ? 0.5 : -0.5 ;
  1112.             offset_IQt_h.Q = fdata;
  1113.             if (offset_IQt_h.I > MAX_OFFSET_IQ)
  1114.             {
  1115.                 offset_IQt_h.I = MAX_OFFSET_IQ;
  1116.             }
  1117.             else if(offset_IQt_h.I < MIN_OFFSET_IQ)
  1118.             {
  1119.                 offset_IQt_h.I = MIN_OFFSET_IQ;
  1120.             }
  1121.             if (offset_IQt_h.Q > MAX_OFFSET_IQ)
  1122.             {
  1123.                 offset_IQt_h.Q = MAX_OFFSET_IQ;
  1124.             }
  1125.             else if(offset_IQt_h.Q < MIN_OFFSET_IQ)
  1126.             {
  1127.                 offset_IQt_h.Q = MIN_OFFSET_IQ;
  1128.             }
  1129.             log->Add( DateToStr(Date()) +  " " + CurrentTimeStr() +
  1130.                       " Evaluate OffsetI = " + IntToStr( offset_IQt_h.I ) +
  1131.                       ", OffsetQ = " + IntToStr( offset_IQt_h.Q )
  1132.                     );
  1133.            l1cal_txiq.bbtx_trimI_h   = trim_IQt_h.I;
  1134.            l1cal_txiq.bbtx_trimQ_h   = trim_IQt_h.Q;
  1135.            l1cal_txiq.bbtx_offsetI_h = offset_IQt_h.I;
  1136.            l1cal_txiq.bbtx_offsetQ_h = offset_IQt_h.Q;
  1137.            l1cal_txiq.bbtx_phsel_h   = c_TxPhasesel_eval_h;
  1138.            S_TXIQ txiq_high;
  1139.            txiq_high.offset_IQ = offset_IQt_h;
  1140.            txiq_high.trim_IQ   = trim_IQt_h;
  1141.            txiq_high.c_TxPhasesel = c_TxPhasesel_eval_h;
  1142.            if (!TXIqCheck_EPSK(false, 2, txiq_high, s_iq_result_high))
  1143.            {
  1144.                return false;
  1145.            }
  1146.         }
  1147. #if 0
  1148.         // phase cal
  1149.            if ((MT6205  != m_pCal->e_bb_chip) &&
  1150.                (MT6205B != m_pCal->e_bb_chip) &&
  1151.     (MT6218  != m_pCal->e_bb_chip) &&
  1152.     (MT6218B != m_pCal->e_bb_chip) &&
  1153.        (MT6219  != m_pCal->e_bb_chip) &&
  1154.         (MT6217  != m_pCal->e_bb_chip) &&
  1155.        (MT6228  != m_pCal->e_bb_chip) &&
  1156.             (MT6227D != m_pCal->e_bb_chip) &&
  1157.     (MT6227  != m_pCal->e_bb_chip) &&
  1158.     (MT6229  != m_pCal->e_bb_chip) &&
  1159.     (MT6226  != m_pCal->e_bb_chip) &&
  1160.             (MT6226D != m_pCal->e_bb_chip) &&
  1161.     (MT6226M != m_pCal->e_bb_chip) &&
  1162.     (MT6230  != m_pCal->e_bb_chip) &&
  1163.     (MT6268T != m_pCal->e_bb_chip) &&
  1164.             (TK6516_MD  != m_pCal->e_bb_chip)
  1165.            )
  1166.         {
  1167.             char cPhaseSel[] = {0, 3};
  1168.             double d_SBS_ph_h[2];
  1169.             double d_PSBS_ph_h[2];
  1170.             for (int i=0; i<2; i++)
  1171.             {
  1172.                 rf_bb_tx_cfg_req.TxPhasesel = cPhaseSel[i];
  1173.                 m_cTXIQ_RUN_Obj.ConfirmCallback = ::CNF_MF;
  1174.                 m_cTXIQ_RUN_Obj.REQ_SetBBTxCfg_Start(m_pCal->e_bbtxcfg_ver, rf_bb_tx_cfg_req);
  1175.                 RestartTimerCal(WM_MF_RF_SET_BB_TX_CFG_FAIL);
  1176.                 SUSPEND_CAL_THREAD
  1177.                 if (m_cTXIQ_RUN_Obj.Get_ConfirmState() != METAAPP_SUCCESS)
  1178.                 {
  1179.                     CalErrorHandler(WM_MF_RF_SET_BB_TX_CFG_FAIL);
  1180.                     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1181.                          " FAIL: Target < RF set BB TX CFG fail."
  1182.                         );
  1183.                     return false;
  1184.                 }
  1185.                 int   pcl[4];
  1186.                 int   cs[4];
  1187.                 APCTxPattern pattern;
  1188.                 cs[0]    = CodingSchemeMCS5;
  1189.                 cs[1]    = CodingSchemeMCS5;
  1190.                 cs[2]    = CodingSchemeMCS5;
  1191.                 cs[3]    = CodingSchemeMCS5;
  1192.                 pcl[0]   = m_sTX_IQ_PCL_HIGH;
  1193.                 pcl[1]   = m_sTX_IQ_PCL_HIGH;
  1194.                 pcl[2]   = m_sTX_IQ_PCL_HIGH;
  1195.                 pcl[3]   = m_sTX_IQ_PCL_HIGH;
  1196.                 pattern = NB_TX_RANDOM_WITH_TSC;
  1197.                 S_MULTI_SLOT_TX_T multi_slot_tx;
  1198.                 multi_slot_tx.b_MultiSlotTXExSupport = m_pCal->b_MultiSlotTxExSupport;
  1199.                 multi_slot_tx.e_bandsel = band_index;
  1200.                 multi_slot_tx.req.arfcn = m_sTX_IQ_ARFCN_HIGH;
  1201.                 multi_slot_tx.req.bsic  = m_cTSC;
  1202.                 multi_slot_tx.req.timeSlotmask = 0x01;
  1203.                 for (int i=0; i<4; i++)
  1204.                 {
  1205.                     multi_slot_tx.req.powerLev[i] = pcl[i];
  1206.             multi_slot_tx.req.cs[i]       = cs[i];
  1207.                 }
  1208.                 multi_slot_tx.req.ta = 0;
  1209.                 multi_slot_tx.req.frames = -99;
  1210.                 multi_slot_tx.req.dacValue = m_sDefault_value;
  1211.                 multi_slot_tx.req.pattern = pattern;
  1212.                 multi_slot_tx.req.pattern_data = 0;
  1213.                 RF_MULTI_SLOT_TX_Obj.ConfirmCallback   = ::ConfirmCallback_MultiSlotTX;
  1214.                 RF_MULTI_SLOT_TX_Obj.REQ_Start(multi_slot_tx);
  1215.                 //RF_MULTI_SLOT_TX_Obj.ConfirmCallback   = ::ConfirmCallback_MultiSlotTX;
  1216.                 //RF_MULTI_SLOT_TX_Obj.REQ_Start(band_index, m_sTX_IQ_ARFCN_HIGH, m_cTSC, cs, pcl, -99, m_sDefault_value, 0x01, 0, true, pattern, 0 );
  1217.                 SUSPEND_CAL_THREAD
  1218.                 if (RF_MULTI_SLOT_TX_Obj.Get_ConfirmState() != METAAPP_SUCCESS)
  1219.                 {
  1220.                     CalErrorHandler(WM_MF_RF_TX_LEVEL_FAIL);
  1221.                     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1222.                           " FAIL: Target < multislot TX fail."
  1223.                         );
  1224.                     return false;
  1225.                 }
  1226.                 // get SBS
  1227.                 if (!m_rct_ctrl.RCT_Fetch_EPSK_Average_IQImbalance(m_pRct, &d_SBS_ph_h[i]))
  1228.                 {
  1229.                     CalErrorHandler(WM_MF_AGE8960_FETCH_EPSK_OOS_FAIL);
  1230.                     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1231.                                   " FAIL : " + m_pRct->as_RCT + " > fetch EPSK original offset fail."
  1232.                                 );
  1233.                     return false;
  1234.                 }
  1235.                 d_PSBS_ph_h[i] = exp(d_SBS_ph_h[i]/10.0*logl(10.0));
  1236.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1237.                      " TxPhasesel = " + IntToStr(cPhaseSel[i]) +
  1238.                      ", SBS = " + Double_To_AnsiString(d_SBS_ph_h[i]) +
  1239.                      ", PSBS = " + Double_To_AnsiString(d_PSBS_ph_h[i])
  1240.                     );
  1241.             } // for(i)
  1242.             // evaluate optimal TxPhasesel
  1243.             double d_opt_TxPhasesel_h = (cPhaseSel[1]*cPhaseSel[1] + 4*d_PSBS_ph_h[0] - 4*d_PSBS_ph_h[1]) / (2*cPhaseSel[1]);
  1244.             rf_bb_tx_cfg_req.TxPhasesel += (d_opt_TxPhasesel_h>=0) ? 0.5 : -0.5 ;
  1245.             log->Add( DateToStr(Date()) +  " " + CurrentTimeStr() +
  1246.                       " Evaluate TxPhasesel = " + IntToStr(rf_bb_tx_cfg_req.TxPhasesel)
  1247.                     );
  1248.             l1cal_txiq.bbtx_phsel_h = rf_bb_tx_cfg_req.TxPhasesel;
  1249.             m_cTXIQ_RUN_Obj.ConfirmCallback = ::CNF_MF;
  1250.             m_cTXIQ_RUN_Obj.REQ_SetBBTxCfg_Start(m_pCal->e_bbtxcfg_ver, rf_bb_tx_cfg_req);
  1251.             RestartTimerCal(WM_MF_RF_SET_BB_TX_CFG_FAIL);
  1252.             SUSPEND_CAL_THREAD
  1253.             if (MF_rf_txiq_ptr->Get_ConfirmState() != METAAPP_SUCCESS)
  1254.             {
  1255.                 CalErrorHandler(WM_MF_RF_SET_BB_TX_CFG_FAIL);
  1256.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1257.                          " FAIL: Target < RF set BB TX CFG fail."
  1258.                         );
  1259.                 return false;
  1260.             }
  1261.         } // phase cal
  1262. #endif
  1263.     }// high band
  1264.     // set calibration flag
  1265.     if ((RF_ID_A60111A == m_pCal->ui_rf_id) ||
  1266.         (RF_ID_AERO2E  == m_pCal->ui_rf_id) ||
  1267.         (RF_ID_MT6140A == m_pCal->ui_rf_id) ||
  1268.         (RF_ID_MT6140B == m_pCal->ui_rf_id) ||
  1269.         (RF_ID_MT6140C == m_pCal->ui_rf_id) ||
  1270.         (RF_ID_MT6140D == m_pCal->ui_rf_id)
  1271.        )
  1272.     {
  1273.         if (s_iq_result_low.b_oos_out_of_range  ||
  1274.             s_iq_result_low.b_sbs_out_of_range  ||
  1275.             s_iq_result_high.b_oos_out_of_range ||
  1276.             s_iq_result_high.b_sbs_out_of_range
  1277.            )
  1278.         {
  1279.             l1cal_txiq.bbtx_isCalibrated = 0;
  1280.         }
  1281.         else
  1282.         {
  1283.             l1cal_txiq.bbtx_isCalibrated = BBTX_CALIBRATED_SCALE;
  1284.         }
  1285.     }
  1286.     else
  1287.     {
  1288.         if (s_iq_result_low.b_oos_out_of_range  ||
  1289.             s_iq_result_low.b_sbs_out_of_range
  1290.            )
  1291.         {
  1292.             l1cal_txiq.bbtx_isCalibrated = 0;
  1293.         }
  1294.         else
  1295.         {
  1296.             l1cal_txiq.bbtx_isCalibrated = BBTX_CALIBRATED_SCALE;
  1297.         }
  1298.     }
  1299.     S_BBTXPARA_CHANGE_FLAG_T flag;
  1300.     flag.b_bbtx_common_mode_voltage = true;
  1301.     flag.b_bbtx_gain = true;
  1302.     flag.b_bbtx_calrcsel = true;
  1303.     flag.b_bbtx_trimI = true;
  1304.     flag.b_bbtx_trimQ = true;
  1305.     flag.b_bbtx_offsetI = true;
  1306.     flag.b_bbtx_offsetQ = true;
  1307.     flag.b_bbtx_isCalibrated = true;
  1308.     flag.b_apc_bat_low_voltage = true;
  1309.     flag.b_apc_bat_high_voltage = true;
  1310.     flag.b_apc_bat_low_temperature = true;
  1311.     flag.b_apc_bat_high_temperature = true;
  1312.     flag.b_bbtx_common_mode_voltage_h = true;
  1313.     flag.b_bbtx_gain_h = true;
  1314.     flag.b_bbtx_calrcsel_h = true;
  1315.     flag.b_bbtx_trimI_h = true;
  1316.     flag.b_bbtx_trimQ_h = true;
  1317.     flag.b_bbtx_offsetI_h = true;
  1318.     flag.b_bbtx_offsetQ_h = true;
  1319.     flag.b_bbtx_phsel = true;
  1320.     flag.b_bbtx_phsel_h = true;
  1321.     MF_rf_txiq_ptr->Set_BBTXChangeFlag(flag);
  1322.     MF_rf_txiq_ptr->Set_BBTXParameters(l1cal_txiq);
  1323.     WriteTxDcOffsetCalResultToFile(as_ID+".cal",Application->ExeName, m_pCal->b_CalResultPath );
  1324.     MF_rf_txiq_ptr->ConfirmCallback = ::ccb_write_txiq_to_nvram;
  1325.     MF_rf_txiq_ptr->REQ_Write_To_NVRAM_Start(m_pCal->ui_rf_id, m_pCal->e_bbtxcfg_ver);
  1326.     RestartTimerCal(WM_MF_NVRAM_TXIQ_WRITE_FAIL);
  1327.     SUSPEND_CAL_THREAD
  1328.     E_METAAPP_RESULT_T state = MF_rf_txiq_ptr->Get_ConfirmState();
  1329.     if (state != METAAPP_SUCCESS)
  1330.     {
  1331.         if (METAAPP_NVRAM_LID_VER_NOT_SUPPORT == state)
  1332.         {
  1333.             CalErrorHandler(WM_MF_NVRAM_EF_L1_TXIQ_LID_VERNO_FAIL);
  1334.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1335.                                   " FAIL : NVRAM_EF_L1_TXIQ_LID version is not support, please update META to latest version. "
  1336.                                 );
  1337.         }
  1338.         else
  1339.         {
  1340.             CalErrorHandler(WM_MF_NVRAM_TXIQ_WRITE_FAIL );
  1341.             log->Add( DateToStr(Date()) +  " " + CurrentTimeStr() +
  1342.                                       " FAIL:  Target< Write txiq value to NVRAM fail "
  1343.                                      );
  1344.         }
  1345.         return false;
  1346.     }
  1347.     log->Add( DateToStr(Date()) +  " " + CurrentTimeStr() +
  1348.                   " Target< Write TXIQ value to NVRAM"
  1349.                 );
  1350.     if (0 == l1cal_txiq.bbtx_isCalibrated)
  1351.     {
  1352.         CalErrorHandler(WM_MF_RF_TX_IQ_CHECK_FAIL);
  1353.         return false;
  1354.     }
  1355.     PostMessage(
  1356.                      ctrl.hPostMsgDestHandle,
  1357.                      WM_MF_RF_TX_IQ_CALIBRATION_DONE,
  1358.                      0,
  1359.                      0
  1360.                     );
  1361.     log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1362.              " ================== TX IQ calibration end ================== "
  1363.            );
  1364.     return true;
  1365. }
  1366. //==============================================================================
  1367. bool __fastcall T_META_factory_calibration::TXIqCheck_EPSK(bool low_band, int stage, S_TXIQ iq, S_TXIQ_RESULT &result)
  1368. {
  1369.     RfBBTXCfg4   rf_bb_tx_cfg_req;
  1370.     result.b_oos_out_of_range = false;
  1371.     result.b_sbs_out_of_range = false;
  1372.     // get BBTxCfg
  1373.     m_cTXIQ_RUN_Obj.ConfirmCallback = ::CNF_MF;
  1374.     m_cTXIQ_RUN_Obj.REQ_GetBBTxCfg_Start(m_pCal->e_bbtxcfg_ver);
  1375.     RestartTimerCal(WM_MF_RF_GET_BB_TX_CFG_FAIL);
  1376.     SUSPEND_CAL_THREAD
  1377.     if (m_cTXIQ_RUN_Obj.Get_ConfirmState() != METAAPP_SUCCESS)
  1378.     {
  1379.         CalErrorHandler(WM_MF_RF_GET_BB_TX_CFG_FAIL);
  1380.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1381.                   " FAIL: Target > RF get BB TX CFG fail."
  1382.                 );
  1383.         return false;
  1384.     }
  1385.     RfBBTXCfg4* p_bbtx_cfg = m_cTXIQ_RUN_Obj.Get_BbTxCfg();
  1386.     rf_bb_tx_cfg_req = *p_bbtx_cfg;
  1387.     if (low_band)
  1388.     {
  1389.       //  bool b_out_of_rangeL_low = false;
  1390.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1391.              " ===================== TX IQ low band stage " + IntToStr(stage) + " check begin =================== "
  1392.            );
  1393.         // set BBTxCfg2
  1394.         rf_bb_tx_cfg_req.TxTrimI    = iq.trim_IQ.I;
  1395.         rf_bb_tx_cfg_req.TxTrimQ    = iq.trim_IQ.Q;
  1396.         rf_bb_tx_cfg_req.TxOffsetI  = iq.offset_IQ.I;
  1397.         rf_bb_tx_cfg_req.TxOffsetQ  = iq.offset_IQ.Q;
  1398.         rf_bb_tx_cfg_req.TxPhasesel = iq.c_TxPhasesel;
  1399.         m_cTXIQ_RUN_Obj.ConfirmCallback = ::CNF_MF;
  1400.         m_cTXIQ_RUN_Obj.REQ_SetBBTxCfg_Start(m_pCal->e_bbtxcfg_ver, rf_bb_tx_cfg_req);
  1401.         RestartTimerCal(WM_MF_RF_SET_BB_TX_CFG_FAIL);
  1402.         SUSPEND_CAL_THREAD
  1403.         if (m_cTXIQ_RUN_Obj.Get_ConfirmState() != METAAPP_SUCCESS)
  1404.         {
  1405.             CalErrorHandler(WM_MF_RF_SET_BB_TX_CFG_FAIL);
  1406.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1407.                              " FAIL: Target < RF set BB TX CFG fail."
  1408.                              );
  1409.             return false;
  1410.         }
  1411.         STOP_RF
  1412.         Sleep(50);
  1413.         int   pcl[4];
  1414.         CodingScheme cs[4];
  1415.         APCTxPattern pattern;
  1416.         cs[0]    = CodingSchemeMCS5;
  1417.         cs[1]    = CodingSchemeMCS5;
  1418.         cs[2]    = CodingSchemeMCS5;
  1419.         cs[3]    = CodingSchemeMCS5;
  1420.         pcl[0]   = m_sTX_IQ_PCL;
  1421.         pcl[1]   = m_sTX_IQ_PCL;
  1422.         pcl[2]   = m_sTX_IQ_PCL;
  1423.         pcl[3]   = m_sTX_IQ_PCL;
  1424.         pattern = NB_TX_RANDOM_WITH_TSC;
  1425.         S_MULTI_SLOT_TX_T multi_slot_tx;
  1426.         multi_slot_tx.b_MultiSlotTXExSupport = m_pCal->b_MultiSlotTxExSupport;
  1427.         E_BANDSEL band_index = String_To_BandIdx(m_asTX_IQ_BAND);
  1428.         multi_slot_tx.e_bandsel = band_index;
  1429.         multi_slot_tx.req.arfcn = m_sTX_IQ_ARFCN;
  1430.         multi_slot_tx.req.bsic  = m_cTSC;
  1431.         multi_slot_tx.req.timeSlotmask = 0x01;
  1432.         for (int i=0; i<4; i++)
  1433.         {
  1434.             multi_slot_tx.req.powerLev[i] = pcl[i];
  1435.             multi_slot_tx.req.cs[i]       = cs[i];
  1436.         }
  1437.         multi_slot_tx.req.ta = 0;
  1438.         multi_slot_tx.req.frames = -99;
  1439.         multi_slot_tx.req.dacValue = m_sDefault_value;
  1440.         multi_slot_tx.req.pattern = pattern;
  1441.         multi_slot_tx.req.pattern_data = 0;
  1442.         RF_MULTI_SLOT_TX_Obj.ConfirmCallback   = ::ConfirmCallback_MultiSlotTX;
  1443.         RF_MULTI_SLOT_TX_Obj.REQ_Start(multi_slot_tx);
  1444.         SUSPEND_CAL_THREAD
  1445.         if (RF_MULTI_SLOT_TX_Obj.Get_ConfirmState() != METAAPP_SUCCESS)
  1446.         {
  1447.             CalErrorHandler(WM_MF_RF_TX_LEVEL_FAIL);
  1448.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1449.                           " FAIL: Target < multislot TX fail."
  1450.                     );
  1451.             return false;
  1452.         }
  1453.         // TX IQ gain imbalance check
  1454.         double d_SBS_Check;
  1455.         double d_OOS_Check;
  1456.         if (!m_rct_ctrl.RCT_Fetch_EPSK_Average_TxIq(m_pRct, &d_SBS_Check, &d_OOS_Check))
  1457.         {
  1458.             CalErrorHandler(WM_MF_AGE8960_FETCH_EPSK_OOS_FAIL);
  1459.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1460.                       " FAIL : " + m_pRct->as_RCT + " > fetch EPSK original offset and IQ imbalance fail."
  1461.                     );
  1462.             return false;
  1463.         }
  1464.         if (d_OOS_Check > m_dTX_IQ_DC_OFFSET_MAX)
  1465.         {
  1466.            // CalErrorHandler(WM_MF_RF_TX_IQ_CHECK_FAIL);
  1467.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1468.                               " FAIL: TX IQ calibration."  +
  1469.                               " , Check TX DC offset = " + Double_To_AnsiString(d_OOS_Check) +
  1470.                               ", Max TX DC offset = " + Double_To_AnsiString( m_dTX_IQ_DC_OFFSET_MAX )
  1471.                     );
  1472.             result.b_oos_out_of_range = true;
  1473.         }
  1474.         else
  1475.         {
  1476.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1477.                               " PASS: TX IQ calibration." +
  1478.                               " , Check TX DC offset = " + Double_To_AnsiString(d_OOS_Check) +
  1479.                               ", Max TX DC offset = " + Double_To_AnsiString( m_dTX_IQ_DC_OFFSET_MAX )
  1480.                     );
  1481.         }
  1482.         // TX IQ gain imbalnce check
  1483.         if (d_SBS_Check > m_dTX_IQ_GAIN_IMBALANCE_MAX)
  1484.         {
  1485.            // CalErrorHandler(WM_MF_RF_TX_IQ_CHECK_FAIL);
  1486.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1487.                               " FAIL: TX IQ calibration."  +
  1488.                               " , Check TX IQ gain imbalance = " + Double_To_AnsiString(d_SBS_Check) +
  1489.                               ", Max TX IQ gain imbalance = " + Double_To_AnsiString( m_dTX_IQ_GAIN_IMBALANCE_MAX )
  1490.                     );
  1491.             result.b_sbs_out_of_range = true;
  1492.         }
  1493.         else
  1494.         {
  1495.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1496.                               " PASS: TX IQ calibration." +
  1497.                               " , Check TX IQ gain imbalance = " + Double_To_AnsiString(d_SBS_Check) +
  1498.                               ", Max TX IQ gain imbalance = " + Double_To_AnsiString( m_dTX_IQ_GAIN_IMBALANCE_MAX )
  1499.                      );
  1500.         }
  1501.         STOP_RF
  1502.         result.d_oos = d_OOS_Check;
  1503.         result.d_sbs = d_SBS_Check;
  1504.         log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1505.              " ===================== TX IQ low band stage " + IntToStr(stage) + " check end ===================== "
  1506.            );
  1507.      }
  1508.      else // high band
  1509.      {
  1510.         if ((RF_ID_A60111A == m_pCal->ui_rf_id) ||
  1511.             (RF_ID_AERO2E  == m_pCal->ui_rf_id) ||
  1512.             (RF_ID_MT6140A == m_pCal->ui_rf_id) ||
  1513.             (RF_ID_MT6140B == m_pCal->ui_rf_id) ||
  1514.             (RF_ID_MT6140C == m_pCal->ui_rf_id) ||
  1515.             (RF_ID_MT6140D == m_pCal->ui_rf_id)
  1516.            )
  1517.         {
  1518.            // bool b_out_of_range_high = false;
  1519.             double d_OOS_Check_h;
  1520.             double d_SBS_Check_h;
  1521.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1522.              " ===================== TX IQ high band stage " + IntToStr(stage) + " check begin =================== "
  1523.            );
  1524.             // set BBTxCfg2
  1525.             rf_bb_tx_cfg_req.TxTrimI   = iq.trim_IQ.I;
  1526.             rf_bb_tx_cfg_req.TxTrimQ   = iq.trim_IQ.Q;
  1527.             rf_bb_tx_cfg_req.TxOffsetI = iq.offset_IQ.I;
  1528.             rf_bb_tx_cfg_req.TxOffsetQ = iq.offset_IQ.Q;
  1529.             rf_bb_tx_cfg_req.TxPhasesel = iq.c_TxPhasesel;
  1530.             m_cTXIQ_RUN_Obj.ConfirmCallback = ::CNF_MF;
  1531.             m_cTXIQ_RUN_Obj.REQ_SetBBTxCfg_Start(m_pCal->e_bbtxcfg_ver, rf_bb_tx_cfg_req);
  1532.             RestartTimerCal(WM_MF_RF_SET_BB_TX_CFG_FAIL);
  1533.             SUSPEND_CAL_THREAD
  1534.             if (m_cTXIQ_RUN_Obj.Get_ConfirmState() != METAAPP_SUCCESS)
  1535.             {
  1536.                 CalErrorHandler(WM_MF_RF_SET_BB_TX_CFG_FAIL);
  1537.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1538.                              " FAIL: Target < RF set BB TX CFG fail."
  1539.                              );
  1540.                 return false;
  1541.             }
  1542.             STOP_RF
  1543.             Sleep(50);
  1544.             int   pcl[4];
  1545.             CodingScheme cs[4];
  1546.             APCTxPattern pattern;
  1547.             cs[0]    = CodingSchemeMCS5;
  1548.             cs[1]    = CodingSchemeMCS5;
  1549.             cs[2]    = CodingSchemeMCS5;
  1550.             cs[3]    = CodingSchemeMCS5;
  1551.             pcl[0]   = m_sTX_IQ_PCL_HIGH;
  1552.             pcl[1]   = m_sTX_IQ_PCL_HIGH;
  1553.             pcl[2]   = m_sTX_IQ_PCL_HIGH;
  1554.             pcl[3]   = m_sTX_IQ_PCL_HIGH;
  1555.             pattern = NB_TX_RANDOM_WITH_TSC;
  1556.             S_MULTI_SLOT_TX_T multi_slot_tx;
  1557.             multi_slot_tx.b_MultiSlotTXExSupport = m_pCal->b_MultiSlotTxExSupport;
  1558.             E_BANDSEL band_index = String_To_BandIdx(m_asTX_IQ_BAND_HIGH);
  1559.             multi_slot_tx.e_bandsel = band_index;
  1560.             multi_slot_tx.req.arfcn = m_sTX_IQ_ARFCN_HIGH;
  1561.             multi_slot_tx.req.bsic  = m_cTSC;
  1562.             multi_slot_tx.req.timeSlotmask = 0x01;
  1563.             for (int i=0; i<4; i++)
  1564.             {
  1565.                 multi_slot_tx.req.powerLev[i] = pcl[i];
  1566.                 multi_slot_tx.req.cs[i]       = cs[i];
  1567.             }
  1568.             multi_slot_tx.req.ta = 0;
  1569.             multi_slot_tx.req.frames = -99;
  1570.             multi_slot_tx.req.dacValue = m_sDefault_value;
  1571.             multi_slot_tx.req.pattern = pattern;
  1572.             multi_slot_tx.req.pattern_data = 0;
  1573.             RF_MULTI_SLOT_TX_Obj.ConfirmCallback   = ::ConfirmCallback_MultiSlotTX;
  1574.             RF_MULTI_SLOT_TX_Obj.REQ_Start(multi_slot_tx);
  1575.             SUSPEND_CAL_THREAD
  1576.             if (RF_MULTI_SLOT_TX_Obj.Get_ConfirmState() != METAAPP_SUCCESS)
  1577.             {
  1578.                 CalErrorHandler(WM_MF_RF_TX_LEVEL_FAIL);
  1579.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1580.                           " FAIL: Target < multislot TX fail."
  1581.                         );
  1582.                 return false;
  1583.             }
  1584.             if (!m_rct_ctrl.RCT_Fetch_EPSK_Average_TxIq(m_pRct, &d_SBS_Check_h, &d_OOS_Check_h))
  1585.             {
  1586.                 CalErrorHandler(WM_MF_AGE8960_FETCH_EPSK_OOS_FAIL);
  1587.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1588.                       " FAIL : " + m_pRct->as_RCT + " > fetch EPSK original offset fail."
  1589.                     );
  1590.                 return false;
  1591.             }
  1592.             STOP_RF
  1593.             if (d_OOS_Check_h > m_dTX_IQ_DC_OFFSET_MAX_HIGH)
  1594.             {
  1595.                // CalErrorHandler(WM_MF_RF_TX_IQ_CHECK_FAIL);
  1596.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1597.                               " FAIL: TX IQ calibration."  +
  1598.                               " , Check high band TX DC offset = " + Double_To_AnsiString(d_OOS_Check_h) +
  1599.                               ", Max TX DC offset = " + Double_To_AnsiString( m_dTX_IQ_DC_OFFSET_MAX_HIGH )
  1600.                         );
  1601.                 result.b_oos_out_of_range = true;
  1602.             }
  1603.             else
  1604.             {
  1605.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1606.                               " PASS: TX IQ calibration." +
  1607.                               " , Check high band TX DC offset = " + Double_To_AnsiString(d_OOS_Check_h) +
  1608.                               ", Max TX DC offset = " + Double_To_AnsiString( m_dTX_IQ_DC_OFFSET_MAX_HIGH )
  1609.                          );
  1610.             }
  1611.             // TX IQ gain imbalnce check
  1612.             if (d_SBS_Check_h > m_dTX_IQ_GAIN_IMBALANCE_MAX_HIGH)
  1613.             {
  1614.                // CalErrorHandler(WM_MF_RF_TX_IQ_CHECK_FAIL);
  1615.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1616.                               " FAIL: TX IQ calibration."  +
  1617.                               " , Check high band TX IQ gain imbalance = " + Double_To_AnsiString(d_SBS_Check_h) +
  1618.                               ", Max TX IQ gain imbalance = " + Double_To_AnsiString(m_dTX_IQ_GAIN_IMBALANCE_MAX_HIGH)
  1619.                         );
  1620.                 result.b_sbs_out_of_range = true;
  1621.             }
  1622.             else
  1623.             {
  1624.                 log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1625.                               " PASS: TX IQ calibration." +
  1626.                               " , Check high band TX IQ gain imbalance = " + Double_To_AnsiString(d_SBS_Check_h) +
  1627.                               ", Max TX IQ gain imbalance = " + Double_To_AnsiString(m_dTX_IQ_GAIN_IMBALANCE_MAX_HIGH)
  1628.                         );
  1629.             }
  1630.             result.d_oos = d_OOS_Check_h;
  1631.             result.d_sbs = d_SBS_Check_h;
  1632.             log->Add(DateToStr(Date()) +  " " + CurrentTimeStr() +
  1633.              " ===================== TX IQ high band stage " + IntToStr(stage) + " check end ===================== "
  1634.             );
  1635.         }
  1636.     }
  1637.     return true;
  1638. }
  1639. //------------------------------------------------------------------------------
  1640. ViReal64 __fastcall T_META_factory_calibration::get_TX_Original_Offset(ViReal64  *p_IQTFreqs, ViReal64 *p_IQTResults, ViInt32   IQTTuningCount)
  1641. {
  1642.     for(int i=0; i<IQTTuningCount; i++)
  1643.     {
  1644.         if( *(p_IQTFreqs+i) == IQT_ORIGINAL_OFFSET_FREQ )
  1645.         {
  1646.             return *(p_IQTResults+i);
  1647.         }
  1648.     }
  1649.     return NAN;
  1650. }