⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 meep6000.c

📁 Atheros AP Test with Agilent N4010A source code
💻 C
📖 第 1 页 / 共 3 页
字号:
                                 A_UINT16 tPdGainOverlap, A_INT16 *pMinCalPower, A_UINT16 * pPdGainBoundaries,
                                 A_UINT8 * pPDADCValues, A_UINT16 * xpdGainValues, A_UINT16 numXpdGains)
{
    LIB_DEV_INFO  *pLibDev = gLibInfo.pLibDevArray[devNum];
    A_BOOL    is2GHz = ((pLibDev->mode == MODE_11G) || (pLibDev->mode == MODE_11B));
    int       i, j, k;
    A_INT16   ss;         /* potentially -ve index for taking care of pdGainOverlap */
    A_UINT16  idxL, idxR, numPiers; /* Pier indexes */

    /* filled out Vpd table for all pdGains (chanL) */
    static A_UINT8   vpdTableL[AR6000_NUM_PD_GAINS][AR6000_MAX_PWR_RANGE_IN_HALF_DB];

    /* filled out Vpd table for all pdGains (chanR) */
    static A_UINT8   vpdTableR[AR6000_NUM_PD_GAINS][AR6000_MAX_PWR_RANGE_IN_HALF_DB];

    /* filled out Vpd table for all pdGains (interpolated) */
    static A_UINT8   vpdTableI[AR6000_NUM_PD_GAINS][AR6000_MAX_PWR_RANGE_IN_HALF_DB];

    A_UINT8   *pVpdL, *pVpdR, *pPwrL, *pPwrR;
    A_UINT8   minPwrT4[AR6000_NUM_PD_GAINS];
    A_UINT8   maxPwrT4[AR6000_NUM_PD_GAINS];
    A_UINT16  numVpd = 0;
    A_INT16   vpdStep;
    A_INT16   tmpVal;
    A_UINT16  sizeCurrVpdTable, maxIndex, tgtIndex;
    A_BOOL    match;

    /* Trim numPiers for the number of populated channel Piers */
    for (numPiers = 0; numPiers < availPiers; numPiers++) {
        if (bChans[numPiers] == AR6000_BCHAN_UNUSED) {
            break;
        }
    }

    /* Find pier indexes around the current channel */
    match = getLowerUpperIndex(FREQ2FBIN(freq, is2GHz), bChans,
                       numPiers, &idxL, &idxR);

    if (match) {
        /* Directly fill both vpd tables from the matching index */
        minPwrT4[0] = pRawDataSet[idxL].pwrPdg0[0];
        minPwrT4[1] = pRawDataSet[idxL].pwrPdg1[0];
        maxPwrT4[0] = pRawDataSet[idxL].pwrPdg0[3];
        maxPwrT4[1] = pRawDataSet[idxL].pwrPdg1[4];
        ar6000FillVpdTable(minPwrT4[0], maxPwrT4[0], pRawDataSet[idxL].pwrPdg0,
                           pRawDataSet[idxL].vpdPdg0, 4, vpdTableI[0]);
        ar6000FillVpdTable(minPwrT4[1], maxPwrT4[1], pRawDataSet[idxL].pwrPdg1,
                           pRawDataSet[idxL].vpdPdg1, 5, vpdTableI[1]);
    } else {
        for (i = 0; i < numXpdGains; i++) {
            if (i == 0) {
                numVpd = 4;
                pVpdL = pRawDataSet[idxL].vpdPdg0;
                pPwrL = pRawDataSet[idxL].pwrPdg0;
                pVpdR = pRawDataSet[idxR].vpdPdg0;
                pPwrR = pRawDataSet[idxR].pwrPdg0;
            } else {
                numVpd = 5;
                pVpdL = pRawDataSet[idxL].vpdPdg1;
                pPwrL = pRawDataSet[idxL].pwrPdg1;
                pVpdR = pRawDataSet[idxR].vpdPdg1;
                pPwrR = pRawDataSet[idxR].pwrPdg1;
            }

            /* Start Vpd interpolation from the max of the minimum powers */
            minPwrT4[i] = A_MAX(pPwrL[0], pPwrR[0]);

            /* End Vpd interpolation from the min of the max powers */
            maxPwrT4[i] = A_MIN(pPwrL[numVpd - 1], pPwrR[numVpd - 1]);
            assert(maxPwrT4[i] > minPwrT4[i]);

            /* Fill pier Vpds */
            ar6000FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL, numVpd, vpdTableL[i]);
            ar6000FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR, numVpd, vpdTableR[i]);

            /* Interpolate the final vpd */
            for (j = 0; j < (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
                vpdTableI[i][j] = interpolate(FREQ2FBIN(freq, is2GHz), bChans[idxL],
                                               bChans[idxR], vpdTableL[i][j], vpdTableR[i][j]);
            }
        }
    }
    *pMinCalPower = minPwrT4[0] / 2;

    k = 0; /* index for the final table */
    for (i = 0; i < numXpdGains; i++) {
        if (i == (numXpdGains - 1)) {
            pPdGainBoundaries[i] = maxPwrT4[i] / 2;
        } else {
            pPdGainBoundaries[i] = ((maxPwrT4[i] + minPwrT4[i+1]) / 4 );
        }
        pPdGainBoundaries[i] = A_MIN(63, pPdGainBoundaries[i]);

        /* Find starting index for this pdGain */
        if (i == 0) {
            ss = 0; /* for the first pdGain, start from index 0 */
        } else {
            ss = (pPdGainBoundaries[i-1] - (minPwrT4[i] / 2)) - tPdGainOverlap + 1;
        }
        vpdStep = (vpdTableI[i][1] - vpdTableI[i][0]);
        vpdStep = ((vpdStep < 1) ? 1 : vpdStep);
        /*
         *-ve ss indicates need to extrapolate data below for this pdGain
         */
        while ((ss < 0) && (k < (AR6000_NUM_PDADC_VALUES - 1))) {
            tmpVal = (vpdTableI[i][0] + ss * vpdStep);
            pPDADCValues[k++] = ((tmpVal < 0) ? 0 : tmpVal);
            ss++;
        }

        sizeCurrVpdTable = (maxPwrT4[i] - minPwrT4[i]) / 2;
        tgtIndex = pPdGainBoundaries[i] + tPdGainOverlap - (minPwrT4[i] / 2);
        maxIndex = (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;

        while ((ss < maxIndex) && (k < (AR6000_NUM_PDADC_VALUES - 1))) {
            pPDADCValues[k++] = vpdTableI[i][ss++];
        }

        vpdStep = (vpdTableI[i][sizeCurrVpdTable - 1] - vpdTableI[i][sizeCurrVpdTable - 2]);
        vpdStep = ((vpdStep < 1) ? 1 : vpdStep);
        /*
         * for last gain, pdGainBoundary == Pmax_t2, so will
         * have to extrapolate
         */
        if (tgtIndex > maxIndex) {  /* need to extrapolate above */
            while ((ss <= tgtIndex) && (k < (AR6000_NUM_PDADC_VALUES - 1))) {
                tmpVal = (vpdTableI[i][sizeCurrVpdTable - 1] +
                          (ss - maxIndex) * vpdStep);
                pPDADCValues[k++] = (tmpVal > 255) ? 255 : tmpVal;
                ss++;
            }
        }               /* extrapolated above */
    }                   /* for all pdGainUsed */

    /* Fill out pdGainBoundaries - only up to 2 allowed here, but hardware allows up to 4 */
    while (i < AR6000_PD_GAINS_IN_MASK) {
        pPdGainBoundaries[i] = pPdGainBoundaries[i-1];
        i++;
    }

    while (k < AR6000_NUM_PDADC_VALUES) {
        pPDADCValues[k] = pPDADCValues[k-1];
        k++;
    }
    return;
}

/**************************************************************
 * getLowerUppderIndex
 *
 * Return indices surrounding the value in sorted integer lists.
 * Requirement: the input list must be monotonically increasing
 *     and populated up to the list size
 * Returns: match is set if an index in the array matches exactly
 *     or a the target is before or after the range of the array.
 */
static A_BOOL
getLowerUpperIndex(A_UINT8 target, A_UINT8 *pList, A_UINT16 listSize,
                   A_UINT16 *indexL, A_UINT16 *indexR)
{
    A_UINT16 i;

    /*
     * Check first and last elements for beyond ordered array cases.
     */
    if (target <= pList[0]) {
        *indexL = *indexR = 0;
        return TRUE;
    }
    if (target >= pList[listSize-1]) {
        *indexL = *indexR = listSize - 1;
        return TRUE;
    }

    /* look for value being near or between 2 values in list */
    for (i = 0; i < listSize - 1; i++) {
        /*
         * If value is close to the current value of the list
         * then target is not between values, it is one of the values
         */
        if (pList[i] == target) {
            *indexL = *indexR = i;
            return TRUE;
        }
        /*
         * Look for value being between current value and next value
         * if so return these 2 values
         */
        if (target < pList[i + 1]) {
            *indexL = i;
            *indexR = i + 1;
            return FALSE;
        }
    }
    assert(0);
    return FALSE;
}

/**************************************************************
 * ar6000FillVpdTable
 *
 * Fill the Vpdlist for indices Pmax-Pmin
 * Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4
 */
static A_BOOL
ar6000FillVpdTable(A_UINT8 pwrMin, A_UINT8 pwrMax, A_UINT8 *pPwrList,
                   A_UINT8 *pVpdList, A_UINT16 numIntercepts, A_UINT8 *pRetVpdList)
{
    A_UINT16  i, k;
    A_UINT8   currPwr = pwrMin;
    A_UINT16  idxL, idxR;

    assert(pwrMax > pwrMin);
    for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
        getLowerUpperIndex(currPwr, pPwrList, numIntercepts,
                           &(idxL), &(idxR));
        if (idxR < 1)
            idxR = 1;           /* extrapolate below */
        if (idxL == numIntercepts - 1)
            idxL = numIntercepts - 2;   /* extrapolate above */
        if (pPwrList[idxL] == pPwrList[idxR])
            k = pVpdList[idxL];
        else
            k = ( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
                  (pPwrList[idxR] - pPwrList[idxL]) );
        assert(k < 256);
        pRetVpdList[i] = (A_UINT8)k;
        currPwr += 2;               /* half dB steps */
    }

    return TRUE;
}

/**************************************************************************
 * interpolate
 *
 * Returns signed interpolated or the scaled up interpolated value
 */
static A_INT16
interpolate(A_UINT16 target, A_UINT16 srcLeft, A_UINT16 srcRight,
            A_INT16 targetLeft, A_INT16 targetRight)
{
    A_INT16 rv;

    if (srcRight == srcLeft) {
        rv = targetLeft;
    } else {
        rv = ((target - srcLeft) * targetRight +
              (srcRight - target) * targetLeft) / (srcRight - srcLeft);
    }
    return rv;
}

/**************************************************************************
 * fbin2freq
 *
 * Get channel value from binary representation held in eeprom
 * RETURNS: the frequency in MHz
 */
static A_UINT16
fbin2freq(A_UINT8 fbin, A_BOOL is2GHz)
{
    /*
     * Reserved value 0xFF provides an empty definition both as
     * an fbin and as a frequency - do not convert
     */
    if (fbin == AR6000_BCHAN_UNUSED) {
        return fbin;
    }

    return ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
}

void getAR6000Struct(
 A_UINT32 devNum,
 void **ppReturnStruct,     //return ptr to struct asked for
 A_UINT32 *pNumBytes        //return the size of the structure
)
{
    LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
    
    *ppReturnStruct = pLibDev->ar6kEep;
    *pNumBytes = sizeof(AR6K_EEPROM);
    return;
}

void
ar6000GetPowerPerRateTable(A_UINT32 devNum, A_UINT16 freq, A_INT16 *pRatesPower)
{
    LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
    A_UINT16 cfgCtl = pLibDev->ar6kEep->baseEepHeader.regDmn & 0xFF;
    A_UINT16 twiceAntennaReduction = (cfgCtl = 0x10) ? 6 : 0;
    A_UINT16 powerLimit = AR6000_MAX_RATE_POWER;

    switch (pLibDev->mode) {
    case MODE_11A:
        cfgCtl |= CTL_11A;
        break;
    case MODE_11G:
    case MODE_11O:
        cfgCtl |= CTL_11G;
        break;
    case MODE_11B:
        cfgCtl |= CTL_11B;
        break;
    default:
        assert(0);
    }

    assert(pRatesPower);
    ar6000SetPowerPerRateTable(devNum, freq, (A_UINT16 *)pRatesPower, cfgCtl, twiceAntennaReduction, powerLimit);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -