📄 cal_gen3.c
字号:
xpd_mask = pRawDataset->xpd_mask;
for (jj = 0; jj < NUM_XPD_PER_CHANNEL; jj++) {
if (((xpd_mask >> jj) & 1) > 0) {
if (kk > 1) {
uiPrintf("A maximum of 2 xpd_gains supported in raw data\n");
exit(0);
}
xgain_list[kk++] = (A_UINT16) jj;
}
}
pCalDataset->numChannels = pRawDataset->numChannels;
for (ii = 0; ii < pCalDataset->numChannels; ii++) {
pCalCh = &(pCalDataset->pDataPerChannel[ii]);
pRawCh = &(pRawDataset->pDataPerChannel[ii]);
pCalCh->channelValue = pRawCh->channelValue;
pCalCh->maxPower_t4 = pRawCh->maxPower_t4;
jj = xgain_list[0];
pCalCh->pcd1_xg0 = (pRawCh->pDataPerXPD[jj].pcdac[0]);
pCalCh->pcd2_delta_xg0 = (pRawCh->pDataPerXPD[jj].pcdac[1] - pRawCh->pDataPerXPD[jj].pcdac[0]);
pCalCh->pcd3_delta_xg0 = (pRawCh->pDataPerXPD[jj].pcdac[2] - pRawCh->pDataPerXPD[jj].pcdac[1]);
pCalCh->pcd4_delta_xg0 = (pRawCh->pDataPerXPD[jj].pcdac[3] - pRawCh->pDataPerXPD[jj].pcdac[2]);
pCalCh->pwr1_xg0 = pRawCh->pDataPerXPD[jj].pwr_t4[0];
pCalCh->pwr2_xg0 = pRawCh->pDataPerXPD[jj].pwr_t4[1];
pCalCh->pwr3_xg0 = pRawCh->pDataPerXPD[jj].pwr_t4[2];
pCalCh->pwr4_xg0 = pRawCh->pDataPerXPD[jj].pwr_t4[3];
if (xgain_list[1] != 0xDEAD) {
jj = xgain_list[1];
pCalCh->pwr1_xg3 = pRawCh->pDataPerXPD[jj].pwr_t4[0];
pCalCh->pwr2_xg3 = pRawCh->pDataPerXPD[jj].pwr_t4[1];
pCalCh->pwr3_xg3 = pRawCh->pDataPerXPD[jj].pwr_t4[2];
} else {
pCalCh->pwr1_xg3 = 0;
pCalCh->pwr2_xg3 = 0;
pCalCh->pwr3_xg3 = 0;
}
}
}
void fill_words_for_eeprom_gen3(A_UINT32 *word, A_UINT16 numWords, A_UINT16 *fbin,
A_UINT16 dbmmask, A_UINT16 pcdmask, A_UINT16 freqmask)
{
A_UINT16 idx = 0;
EEPROM_DATA_PER_CHANNEL_GEN3 *pCalCh;
A_UINT16 ii;
A_UINT16 pcdac_delta_mask = 0x1F;
A_UINT16 pcdac_mask = 0x3F;
A_UINT16 numPiers;
// Group 1. 11a Frequency pier locations
if(CalSetup.calPower && CalSetup.Amode)
{
word[idx++] = ( (fbin[1] & freqmask) << 8) | (fbin[0] & freqmask) ;
word[idx++] = ( (fbin[3] & freqmask) << 8) | (fbin[2] & freqmask) ;
word[idx++] = ( (fbin[5] & freqmask) << 8) | (fbin[4] & freqmask) ;
word[idx++] = ( (fbin[7] & freqmask) << 8) | (fbin[6] & freqmask) ;
word[idx++] = ( (fbin[9] & freqmask) << 8) | (fbin[8] & freqmask) ;
} else {
/*
for (jj=0; jj<5; jj++)
{
word[idx++] = 0x0000;
}
*/
}
//Group 2. 11a calibration data for all frequency piers
if(CalSetup.calPower && CalSetup.Amode)
{
for (ii=0; ii<pCalDataset_gen3[MODE_11a]->numChannels; ii++)
{
pCalCh = &(pCalDataset_gen3[MODE_11a]->pDataPerChannel[ii]);
word[idx++] = ( ( (pCalCh->pwr1_xg0 & dbmmask) << 0) |
( (pCalCh->pwr2_xg0 & dbmmask) << 8) );
word[idx++] = ( ( (pCalCh->pwr3_xg0 & dbmmask) << 0) |
( (pCalCh->pwr4_xg0 & dbmmask) << 8) );
word[idx++] = ( ( (pCalCh->pcd2_delta_xg0 & pcdac_delta_mask) << 0) |
( (pCalCh->pcd3_delta_xg0 & pcdac_delta_mask) << 5) |
( (pCalCh->pcd4_delta_xg0 & pcdac_delta_mask) << 10) );
word[idx++] = ( ( (pCalCh->pwr1_xg3 & dbmmask) << 0) |
( (pCalCh->pwr2_xg3 & dbmmask) << 8) );
word[idx++] = ( ( (pCalCh->pwr3_xg3 & dbmmask) << 0) |
// ( (pCalCh->maxPower_t4 & dbmmask) << 8) );
( (pCalCh->pcd1_xg0 & pcdac_mask) << 8) ); // starting eeprom 4.3
}
/*
if(NUM_PIERS > pCalDataset_gen3[MODE_11a]->numChannels)
{
for (ii = pCalDataset_gen3[MODE_11a]->numChannels; ii < NUM_PIERS; ii++) {
word[idx++] = 0x0000;
word[idx++] = 0x0000;
word[idx++] = 0x0000;
word[idx++] = 0x0000;
word[idx++] = 0x0000;
}
}
*/
} else
{
/*
for (ii=0; ii < NUM_PIERS; ii++)
{
for (jj=0; jj<5; jj++)
{
word[idx++] = 0x0000;
}
}
*/
}
//Group 3. 11b Calibration Piers and Calibration Information
if(CalSetup.calPower && CalSetup.Bmode)
{
numPiers = pCalDataset_gen3[MODE_11b]->numChannels;
for (ii=0; ii<numPiers; ii++)
{
fbin[ii] = freq2fbin(pCalDataset_gen3[MODE_11b]->pChannels[ii]) ;
}
if (numPiers < NUM_PIERS_2p4) {
for (ii=numPiers; ii<NUM_PIERS_2p4; ii++) {
fbin[ii] = 0;
}
}
/*
word[idx++] = ( (fbin[1] & freqmask) << 8) | (fbin[0] & freqmask) ;
word[idx++] = (fbin[2] & freqmask) ;
*/
for (ii=0; ii<pCalDataset_gen3[MODE_11b]->numChannels; ii++)
{
pCalCh = &(pCalDataset_gen3[MODE_11b]->pDataPerChannel[ii]);
word[idx++] = ( ( (pCalCh->pwr1_xg0 & dbmmask) << 0) |
( (pCalCh->pwr2_xg0 & dbmmask) << 8) );
word[idx++] = ( ( (pCalCh->pwr3_xg0 & dbmmask) << 0) |
( (pCalCh->pwr4_xg0 & dbmmask) << 8) );
word[idx++] = ( ( (pCalCh->pcd2_delta_xg0 & pcdac_delta_mask) << 0) |
( (pCalCh->pcd3_delta_xg0 & pcdac_delta_mask) << 5) |
( (pCalCh->pcd4_delta_xg0 & pcdac_delta_mask) << 10) );
word[idx++] = ( ( (pCalCh->pwr1_xg3 & dbmmask) << 0) |
( (pCalCh->pwr2_xg3 & dbmmask) << 8) );
word[idx++] = ( ( (pCalCh->pwr3_xg3 & dbmmask) << 0) |
// ( (pCalCh->maxPower_t4 & dbmmask) << 8) );
( (pCalCh->pcd1_xg0 & pcdac_mask) << 8) ); // starting eeprom 4.3
}
/*
if(NUM_PIERS > pCalDataset_gen3[MODE_11a]->numChannels)
{
for (ii = pCalDataset_gen3[MODE_11a]->numChannels; ii < NUM_PIERS; ii++) {
word[idx++] = 0x0000;
word[idx++] = 0x0000;
word[idx++] = 0x0000;
word[idx++] = 0x0000;
word[idx++] = 0x0000;
}
}
*/
} else
{
/*
for (ii=0; ii < NUM_PIERS; ii++)
{
for (jj=0; jj<5; jj++)
{
word[idx++] = 0x0000;
}
}
*/
}
//Group 4. 11g Calibration Piers and Calibration Information
if(CalSetup.calPower && CalSetup.Gmode)
{
numPiers = pCalDataset_gen3[MODE_11g]->numChannels;
for (ii=0; ii<numPiers; ii++)
{
fbin[ii] = freq2fbin(pCalDataset_gen3[MODE_11g]->pChannels[ii]) ;
}
if (numPiers < NUM_PIERS_2p4) {
for (ii=numPiers; ii<NUM_PIERS_2p4; ii++) {
fbin[ii] = 0;
}
}
/*
word[idx++] = ( (fbin[1] & freqmask) << 8) | (fbin[0] & freqmask) ;
word[idx++] = (fbin[2] & freqmask) ;
*/
for (ii=0; ii<pCalDataset_gen3[MODE_11g]->numChannels; ii++)
{
pCalCh = &(pCalDataset_gen3[MODE_11g]->pDataPerChannel[ii]);
word[idx++] = ( ( (pCalCh->pwr1_xg0 & dbmmask) << 0) |
( (pCalCh->pwr2_xg0 & dbmmask) << 8) );
word[idx++] = ( ( (pCalCh->pwr3_xg0 & dbmmask) << 0) |
( (pCalCh->pwr4_xg0 & dbmmask) << 8) );
word[idx++] = ( ( (pCalCh->pcd2_delta_xg0 & pcdac_delta_mask) << 0) |
( (pCalCh->pcd3_delta_xg0 & pcdac_delta_mask) << 5) |
( (pCalCh->pcd4_delta_xg0 & pcdac_delta_mask) << 10) );
word[idx++] = ( ( (pCalCh->pwr1_xg3 & dbmmask) << 0) |
( (pCalCh->pwr2_xg3 & dbmmask) << 8) );
word[idx++] = ( ( (pCalCh->pwr3_xg3 & dbmmask) << 0) |
// ( (pCalCh->maxPower_t4 & dbmmask) << 8) );
( (pCalCh->pcd1_xg0 & pcdac_mask) << 8) ); // starting eeprom 4.3
}
/*
if(NUM_PIERS > pCalDataset_gen3[MODE_11a]->numChannels)
{
for (ii = pCalDataset_gen3[MODE_11a]->numChannels; ii < NUM_PIERS; ii++) {
word[idx++] = 0x0000;
word[idx++] = 0x0000;
word[idx++] = 0x0000;
word[idx++] = 0x0000;
word[idx++] = 0x0000;
}
}
*/
} else
{
/*
for (ii=0; ii < NUM_PIERS; ii++)
{
for (jj=0; jj<5; jj++)
{
word[idx++] = 0x0000;
}
}
*/
}
fill_Target_Power_and_Test_Groups(&(word[idx]), (A_UINT16)(numWords - idx + 1), dbmmask, pcdmask, freqmask);
}
void read_dataset_from_file_gen3(RAW_DATA_STRUCT_GEN3 *pDataSet, char *filename) {
uiPrintf("Reading raw data from file not supported for gen3 yet. Please provide force_piers_list\n");
exit(0);
}
void golden_iq_cal(A_UINT32 devNum, A_UINT32 mode, A_UINT32 channel) {
A_UINT32 maxIter = 40;
A_UINT32 iter = 0;
A_UINT32 complete_timeout = 4000;
A_BOOL TransmitOn = FALSE;
configSetup.eepromLoad = 1;
art_setResetParams(devNum, configSetup.pCfgFile, (A_BOOL)configSetup.eepromLoad,
(A_BOOL)configSetup.eepromHeaderLoad, (A_UCHAR)mode, configSetup.use_init);
art_resetDevice(devNum, txStation, NullID, channel, 0);
art_forceSinglePowerTxMax(devNum, 10);
waitForAck(CalSetup.customerDebug);
while (!verifyAckStr("Done with iq_cal for mode") && (iter++ < (maxIter + 1))) {
if (REWIND_TEST) {
if (TransmitOn) {
art_txContEnd(devNum);
TransmitOn = FALSE;
}
return;
}
//art_txDataSetup(devNum, IQ_CAL_RATEMASK, rxStation, 4*IQ_CAL_NUMPACKETS, 100, pattern, 2, 0, 2, 1);
if (!TransmitOn) {
art_txContBegin(devNum, CONT_FRAMED_DATA, RANDOM_PATTERN, IQ_CAL_RATE, DESC_ANT_A | USE_DESC_ANT);
TransmitOn = TRUE;
}
Sleep(100);
sendAck(devNum, "Ready to TX for iq_cal at", mode, channel, 0,CalSetup.customerDebug);
// Sleep(30);
// art_txDataBegin(devNum, complete_timeout, 0);
waitForAck(CalSetup.customerDebug);
if (verifyAckStr("Failed iq_cal. Rewind Test")) {
uiPrintf("\n\n*************** Failed iq_cal for mode %s. Retry. ********************\n",modeName[calModeFor[mode]]);
uiPrintf("recv Str = %s\n", ackRecvStr);
REWIND_TEST = TRUE;
}
}
if (TransmitOn) {
art_txContEnd(devNum);
TransmitOn = FALSE;
}
sendAck(devNum, "Consent to quit iq_cal", 0, 0, 0, CalSetup.customerDebug);
}
void dut_iq_cal(A_UINT32 devNum, A_UINT32 mode, A_UINT32 channel) {
// mode is the devlibmode here
A_UINT32 iter = 0;
A_UINT32 maxIter = 40;
A_UINT32 iterRX = 0;
A_UINT32 maxIterRX = 200;
// double pwr_meas_i = 0;
// double pwr_meas_q = 0;
A_UINT32 pwr_meas_i = 0;
A_UINT32 pwr_meas_q = 0;
A_UINT32 iq_corr_meas = 0, iq_corr_neg = 0;
A_UINT32 i_coeff, q_coeff;
A_UINT32 rddata;
uiPrintf("\nPerforming iq_cal for mode %s :", modeName[calModeFor[mode]]);
sendAck(devNum, "Initiate iq_cal at mode", mode, channel, 0, CalSetup.customerDebug);
// art_resetDevice(devNum, rxStation, NullID, channel, 0);
while ((iter++ < maxIter) &&
((pwr_meas_i < 0x0FFFFFFF) || (pwr_meas_q < 0x0FFFFFFF) || (iq_corr_meas == 0)) ){
art_resetDevice(devNum, rxStation, NullID, channel, 0);
sendAck(devNum, "Ready to RX for iq_cal at", mode, channel, iter, CalSetup.customerDebug);
waitForAck(CalSetup.customerDebug) ;
if (!verifyAckStr("Ready to TX for iq_cal at")) {
uiPrintf("ERROR: Got out of sync in iq_cal [ackStr: %s]\n", ackRecvStr);
exit(0);
}
Sleep(10);
art_regWrite(devNum, 0x9920, 0x1f000) ; // enable iq_cal and set sample size to 11
rddata = art_regRead(devNum, 0x9920);
rddata = (rddata >> 16) & 0x1;
iterRX = 0;
while ((rddata == 0x1) && (iterRX++ < maxIterRX)){
rddata = art_regRead(devNum, 0x9920);
rddata = (rddata >> 16) & 0x1;
Sleep(10);
// uiPrintf("[%d] rddata = %d\n", iterRX, rddata);
}
if (iterRX == maxIterRX) {
uiPrintf("iq_cal iter : %d.\n", iter);
}
pwr_meas_i = 0;
pwr_meas_q = 0;
iq_corr_meas = 0;
pwr_meas_i = art_regRead(devNum, (0x9800 + (260 << 2))) ;
pwr_meas_q = art_regRead(devNum, (0x9800 + (261 << 2))) ;
iq_corr_meas = art_regRead(devNum, (0x9800 + (262 << 2))) ;
// uiPrintf("SNOOP: pwr_I = 0x%x, pwr_Q = 0x%x, IQ_Corr = 0x%x\n", pwr_meas_i, pwr_meas_q, iq_corr_meas);
iq_corr_neg = 0;
}
if ((iter > maxIter) &&
((pwr_meas_i < 0x0FFFFFFF) || (pwr_meas_q < 0x0FFFFFFF) || (iq_corr_meas == 0)) ){
uiPrintf("\n\n*************** Failed iq_cal for mode %s. Retry. ********************\n",modeName[calModeFor[mode]]);
REWIND_TEST = TRUE;
sendAck(devNum, "Failed iq_cal. Rewind Test", 0, 0, 0, CalSetup.customerDebug);
return;
}
if (iq_corr_meas >= 0x80000000) {
iq_corr_meas = 0xFFFFFFFF - iq_corr_meas;
iq_corr_neg = 1;
}
i_coeff = (A_UINT32)floor((128.0*(double)iq_corr_meas)/(((double)pwr_meas_i+(double)pwr_meas_q)/2.0) + 0.5);
q_coeff = (A_UINT32)floor((((double)pwr_meas_i/(double)pwr_meas_q) - 1.0)*128.0 + 0.5);
// uiPrintf("SNOOP: interm i_coeff = %d, q_coeff = %d\n", i_coeff, q_coeff);
if (CalSetup.customerDebug > 0) {
uiPrintf("pwr_I = %d, pwr_Q = %d, IQ_Corr = %d\n", pwr_meas_i, pwr_meas_q, iq_corr_meas);
}
// print i_coeff/q_coeff before truncation.
uiPrintf(" i_coeff = %d, q_coeff = %d\n", i_coeff, q_coeff);
i_coeff = (i_coeff & 0x3f);
if (iq_corr_neg == 0x0) {
i_coeff = 0x40 - i_coeff;
}
q_coeff = q_coeff & 0x1f;
// uiPrintf(" i_coeff = %d, q_coeff = %d\n", i_coeff, q_coeff);
rddata = art_regRead(devNum, 0x9920);
rddata = rddata | (1 << 11) | (i_coeff << 5) | q_coeff;
art_regWrite(devNum, 0x9920, rddata);
CalSetup.iqcal_i_corr[calModeFor[mode]] = i_coeff;
CalSetup.iqcal_q_corr[calModeFor[mode]] = q_coeff;
sendAck(devNum, "Done with iq_cal for mode", mode, channel, 0, CalSetup.customerDebug);
waitForAck(CalSetup.customerDebug);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -