📄 cal_dll.cpp
字号:
// cal_dll.cpp
// n steffen
// May 11, 2000
//
// calibration algorithms here
//
// June 27, 2000
// Replaced pac_cal_type with PACCalType
//
// August 3, 2000
// Ver. 6.09
// Use power level 1 instead of 0 (index 4 instead of index 3) as
// highest power when calibrating DCS and PCS Tx.
//
// September 25, 2000
// GenReport now accepts the whole CurParm structure instead of CurParm.test_pcs
// Did this to pass in the start.end ramp values for Conexant PAC cal
//
// November 22, 2000
// Ver. 6.25
// Use average slope over all 3 segments when calculating Conexant ramps
//
// December 2, 2000
// Ver. 6.26
// No longer report APC_DAC_VALUE_TOO_LARGE when it's really underflowed.
// Made the pedestal's delta from the last value that made it correct a
// parameter (at compile time).
//
// December 30, 2000
// Ver. 6.29
// Add capability to skip rx calibration and instead copy from default file to system parameter file
//
// January 30, 2001
// Ver. 6.37
// Added WriteLog()
//
#include "caltypes.h"
#include "error.h"
#include "hs.h"
#include "measure.h"
#include "cal_class.h"
#define TWO_STEPS 2
#define FULL_GSM_RAMP_STEPS 15
#define FULL_DCS_RAMP_STEPS 16
#define FULL_PCS_RAMP_STEPS 16
#define TWO_STEPS 2
#define RAMP_LENGTH 32 // entries in 1 ramp
#define NUMBER_OF_RX_CAL_POINTS 2
#define GSYS_SIZE 64
#define MIN_GSYS_34 -2000
#define MAX_GSYS_34 2000
#define PI 3.1415926
#define FREQ_ERROR_TOLERANCE 1000.0
#define OFFSET_ERROR_TOLERANCE 9999999.98
#define PHASE_ERROR_TOLERANCE 5.0
#define RAMP_TABLE_SIZE 19
#define GSM850_FREQ (850.0)
#define GSM_FREQ (900.0)
#define DCS_FREQ (1800.0)
#define PCS_FREQ (1900.0)
#define GSM_TRIAL_PEDESTAL 0x80
#define DCS_TRIAL_PEDESTAL 0x80
#define PCS_TRIAL_PEDESTAL 0x80
#define GSM850_TRIAL_PEDESTAL 0x80
/*
#define RampStartDcs 66
#define RampEndDcs 66
#define RampStartPcs 66
#define RampEndPcs 66
#define RampStartGsm 66
#define RampEndGsm 66
*/
static const double CosSquar[17] =
{
1.000000, 0.990393, 0.961940, 0.915735, 0.853554, 0.777785, 0.691342, 0.597546,
0.500001, 0.402456, 0.308659, 0.222216, 0.146447, 0.084266, 0.038061, 0.009608, 0
};
float TargetTxPwrValue[4][RAMP_TABLE_SIZE]=
{ //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
{32.5, 32.5, 32.5, 32.5, 31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 5}, //GSM
{29.5, 29.5, 29.5, 29.5, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0}, //DCS
{29.5, 29.5, 29.5, 29.5, 27.5, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0},
{32.5, 32.5, 32.5, 32.5, 30.5, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 5}
};
static const unsigned canonical_gsm_ramp[32]=
{
0x0010, 0x006c, 0x0071, 0x007a, 0x0086, 0x0094, 0x00a4, 0x00b5,
0x00c6, 0x00d6, 0x00eb, 0x0117, 0x0162, 0x01c6, 0x023c, 0x0266,
0x023c, 0x01c6, 0x0162, 0x0117, 0x00eb, 0x00d6, 0x00c6, 0x00b5,
0x00a4, 0x0094, 0x0086, 0x007a, 0x0071, 0x006c, 0x006b, 0x0010
};
// canonical DCS/PCS ramp
/*
static const unsigned canonical_dcs_ramp[32]=
{
0x0010, 0x00a4, 0x00ad, 0x00bb, 0x00ce, 0x00e5, 0x00ff, 0x011b,
0x0137, 0x014b, 0x0158, 0x016e, 0x0192, 0x01d6, 0x0259, 0x02ac,
0x0259, 0x01d6, 0x0192, 0x016e, 0x0158, 0x014b, 0x0137, 0x011b,
0x00ff, 0x00e5, 0x00ce, 0x00bb, 0x00ad, 0x00a4, 0x00a3, 0x0010
};
*/
static const unsigned canonical_dcs_ramp[32]=
{
112,114,116,120,125,137,164,225,329,486,709,897,961,961,961,961,
861,592,352,210,144,123,112,102,87,73,63,56,54,54,54,54};
void build_trial_ramp(unsigned ramp[32],float peak,unsigned band,unsigned int pedestal);
//*******************************************************************************
cal::cal()
{
strcpy(log_filename,"cal_log.txt");
}
//*******************************************************************************
void cal::LogTxPowerTable(float *table, unsigned length, float unused)
{
unsigned i;
char string[256];
for(i=0;i<length;i++)
{
if(table[i]!=unused)
{
sprintf(string,"%d\t%f",i,table[i]);
WriteLog(string);
}
}
}
//*******************************************************************************
void cal::WriteLog(char *buf)
{
HANDLE hFile;
unsigned long fp;
unsigned long count;
char cr[2]={0x0d,0x0a};
if(logging)
{
hFile=CreateFile(log_filename,GENERIC_WRITE,FILE_SHARE_READ,NULL,
OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
// go to end of file
fp=SetFilePointer (hFile,0,NULL, FILE_END);
WriteFile(hFile,buf,strlen(buf),&count,NULL);
WriteFile(hFile,cr,2,&count,NULL); // append a newline
CloseHandle(hFile);
}
}
//*******************************************************************************
void cal::InitializeLogFile()
{
HANDLE hFile;
hFile=CreateFile(log_filename,GENERIC_WRITE,FILE_SHARE_READ,NULL,
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
CloseHandle(hFile);
cal_hs.HS_SetLogFilename(log_filename);
cal_measure.SetLogFilename(log_filename);
}
//*******************************************************************************
void cal::InitializeLogFile(char *filename)
{
HANDLE hFile;
strcpy(log_filename,filename);
hFile=CreateFile(log_filename,GENERIC_WRITE,FILE_SHARE_READ,NULL,
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
CloseHandle(hFile);
cal_hs.HS_SetLogFilename(log_filename);
cal_measure.SetLogFilename(log_filename);
}
//*******************************************************************************
void cal::EnableLogging(BOOL enable)
{
logging=enable;
cal_hs.HS_EnableLogging(enable);
cal_measure.EnableLogging(enable);
}
//*******************************************************************************
BOOL cal::SetBand(BandIndex_t b)
{
band=b;
return TRUE;
}
//*******************************************************************************
BOOL cal::SetPACCalType(PACCalType_t type)
{
pac_cal_type=type;
return SUCCESS;
}
//*******************************************************************************
Error_t cal::TestFreqPhase()
{
float FreqError;
float PhaseError;
// start the handset
// cal_hs.HS_SetTxLev(10);
// cal_hs.HS_SetStart();
//Set Handset Freq DAC to value that gives 0 freq error
cal_hs.HS_SetDacVal(cal_data.FreqDacZero);
Sleep(1000);
// Read the Frequency offset
cal_measure.GetFreqOffset(&FreqError);
if(fabs((float)FreqError>FREQ_ERROR_TOLERANCE))
{
cal_hs.HS_SetDacVal(cal_data.FreqDacZero-100);
return FREQ_ERROR;
}
// Read the phase error
cal_measure.GetPhaseError(&PhaseError);
if(fabs((float)FreqError>FREQ_ERROR_TOLERANCE))
{
cal_hs.HS_SetDacVal(cal_data.FreqDacZero-100);
return PHASE_ERROR;
}
// shift the frequency about 5 KHz away from 0
// Need a non-zero freq error to get good accuracy on reported
// Rxlev
// cal_hs.HS_SetDacVal(cal_data.FreqDacZero-100);
// zero the freq error
cal_hs.HS_SetDacVal(cal_data.FreqDacZero);
return SUCCESS;
}
//*******************************************************************************
// Changed 4/29/01 to be band-sensitive when creating the ramp
Error_t cal::CalFreqDac()
{
float Offset1, Offset2;
UInt16 DacVal1, DacVal2;
Error_t stat=SUCCESS;
unsigned trial_ramp[32];
float expected_power=15;
float msrd;
DacVal1 = 0x200;
DacVal2 = 0x300;
// March 15, 2001
// Instead of just using power level 10 built in to the phone,
// generate a canonical ramp that has measurable (integrity=0) power
// start the handset
cal_hs.HS_SetTxLev(10);
if((pac_cal_type==INFINEON) && (cal_measure.GetTesterType()==AGT8960))
{
if(band==GSM)
{
build_trial_ramp(trial_ramp,0x250,GSM,GSM_TRIAL_PEDESTAL);
}
else if (band==DCS)
{
build_trial_ramp(trial_ramp,0x250,DCS,DCS_TRIAL_PEDESTAL);
}
else if (band==PCS)
{
build_trial_ramp(trial_ramp,0x250,PCS,PCS_TRIAL_PEDESTAL);
}
else
{
build_trial_ramp(trial_ramp,0x250,GSM850,GSM850_TRIAL_PEDESTAL);
}
cal_hs.HS_SetRamp(trial_ramp);
Sleep(100);
if(cal_measure.GetTxPower(expected_power,&msrd)==FALSE)
{
return POWER_ERROR;
}
}
else
{
cal_hs.HS_SetStart();
}
//Set Handset Freq DAC value1 dac_val1
cal_hs.HS_SetDacVal(DacVal1);
Sleep(1000);
// Read the Frequency offset offset1
cal_measure.GetFreqOffset(&Offset1);
Sleep(1000);
if(fabs((float)Offset1+OFFSET_ERROR_TOLERANCE)<1) //weidg offset
{
return OFFSET_ERROR;
}
// Set Handset Freq Dac value2 dac_val2
cal_hs.HS_SetDacVal(DacVal2);
Sleep(1000);
// Read the Frequency offset again offset2
cal_measure.GetFreqOffset(&Offset2);
if(fabs((float)Offset2+OFFSET_ERROR_TOLERANCE)<1) //weidg offset
{
return OFFSET_ERROR;
}
if (fabs(Offset1-Offset2)<1)
{
return OFFSET_ERROR;
}
// resolve (dac_val1 - dac_zero) : offset1 = ( dac_val2 - dac_Zero) : offset2
// get dac_zero
cal_data.FreqDacZero = (UInt16)((Offset1 * DacVal2 - Offset2 * DacVal1 )/(Offset1 - Offset2) );
// calculate dac_lsb = offset1/(dac_val1 - dac_zero)
cal_data.FreqDacLsb = (UInt16)(abs((int)Offset1) / abs((int)(DacVal1 - cal_data.FreqDacZero)) );
if(band==DCS)
{
cal_data.FreqDacLsb*=(GSM_FREQ/DCS_FREQ);
}
else if(band==PCS)
{
cal_data.FreqDacLsb*=(GSM_FREQ/PCS_FREQ);
}
else if(band=GSM850)
{
cal_data.FreqDacLsb*=(GSM_FREQ/GSM850_FREQ);
}
// set dac_shift -10 (1024)
cal_data.FreqDacShift = -10;
// calculate dac_multi = 1024/ dac_lsb
if(cal_data.FreqDacLsb)
{
cal_data.FreqDacMulti = (UInt16) (1024/ cal_data.FreqDacLsb );
}
//update the Freqency dac value currently phone using
cal_hs.HS_SetDacVal(cal_data.FreqDacZero);
// shift the frequency about 5 KHz away from 0
// Need a non-zero freq error to get good accuracy on reported
// Rxlev
cal_hs.HS_SetDacVal(cal_data.FreqDacZero-100);
return stat;
}
//*******************************************************************************
Error_t cal::CalTxGsm(UserDefParm_t parms)
{
Parm_t parm;
UInt16 Step;
UInt16 TestTxRampIndex;
float ExpectedTxPwr;
float RealTxLev[RAMP_TABLE_SIZE];
UInt16 TxRampIndex[RAMP_TABLE_SIZE];
float Slope;
float delta_pwr;
UInt16 new_value;
Int16 i;
UInt16 trial_ramp[RAMP_LENGTH];
UInt16 pedestal_success;
unsigned stat;
unsigned first_pass;
unsigned pedestal_stat;
float tx_power;
float sat_power; // tx power at saturation
unsigned sat_dac; // pk dac value at saturation
float highest_unsat_power; // tx power before saturation
unsigned highest_unsat_dac; // pk dac value before saturation
Error_t error;
unsigned hard_upper_limit;
unsigned hard_lower_limit;
unsigned upper_limit;
unsigned lower_limit;
unsigned peak_dac;
unsigned index0,index1;
float msrd0,msrd1;
float Intercept;
Error_t search_stat;
unsigned fine_step;
// Tx cal - set power level in HS. Measure Tx power - add fudge factor to get HP8922 to
// read correctly - needs to be within 3 dB to read correctly. Calculate the slope (dBm/LSB)
// of the power control DAC transfer function.
// 1. set tx power level to 10 (ramp index = 8). Power s/b 23 dBm
// 2. Set tx power level to 16 (ramp index = 14). Power s/b 11 dBm
// set highest power levels to user parameter
TargetTxPwrValue[GSM][0]=TargetTxPwrValue[GSM][1]=TargetTxPwrValue[GSM][2]=
TargetTxPwrValue[GSM][3]=parms.gsm_highest_power;
// get current peak DAC values
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -