?? meeprom.c
字號:
/* mEeprom.c - contians functions for reading eeprom and getting pcdac power settings for all channels */
/* Copyright (c) 2001 Atheros Communications, Inc., All Rights Reserved */
#ident "ACI $Id: //depot/sw/branches/ART_V53_dragon/sw/src/dk/mdk/devlib/mEeprom.c#2 $, $Header: //depot/sw/branches/ART_V53_dragon/sw/src/dk/mdk/devlib/mEeprom.c#2 $"
/*
Revsision history
--------------------
1.0 Created.
*/
#ifdef VXWORKS
#include "vxworks.h"
#endif
#ifdef __ATH_DJGPPDOS__
#include <unistd.h>
#ifndef EILSEQ
#define EILSEQ EIO
#endif // EILSEQ
#define __int64 long long
typedef unsigned long DWORD;
#define Sleep delay
#endif // #ifdef __ATH_DJGPPDOS__
#include "wlantype.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef WIN32
#include <memory.h>
#include <conio.h>
#endif
#include "athreg.h"
#include "manlib.h"
#include "mEeprom.h"
#include "mConfig.h"
#include "mDevtbl.h"
#include <errno.h>
#include "mEEP211.h"
#include "mEEPROM_d.h"
#include "mEEPROM_g.h"
#include "ar2413reg.h"
#include "..\ar6000\mEep6000.h"
#if defined(SPIRIT_AP) || defined(FREEDOM_AP)
// delta macro defined in both mEeprom.h and ar531x.h
// cannot #include ar531x.h
// declaring only the functions and MACROS needed from ar531x.h
UINT8 sysFlashConfigRead(int fcl , int offset);
void sysFlashConfigWrite(int fcl, int offset, UINT8 *data, int len);
#define FLC_RADIOCFG 2
#endif
A_UINT16 intercepts_pre3p2[] = {0,5,10,20,30,50,70,85,90,95,100};
A_UINT16 intercepts[] = {0,10,20,30,40,50,60,70,80,90,100} ;
#define NUM_INTERCEPTS sizeof(intercepts)/sizeof(A_UINT16)
A_UINT16 channels_11b[] = {2412, 2447, 2484};
A_UINT16 channels_11g[] = {2312, 2412, 2484};
A_UINT16 curr_pwr_index_offset; // scale-up factor to make it Pmax referenced power table
static A_UINT16 cornerFixChannels[] = {5180, 5320, 5640, 5825};
#define NUM_CORNER_FIX_CHANNELS sizeof(cornerFixChannels)/sizeof(A_UINT16)
//static void writeCornerCal(A_UINT32 devNum, A_UINT16 channel,MDK_EEP_HEADER_INFO *pHeaderInfo);
//this is static (and a structure), so that getCtlPowerInfo() can return this info
//from library
static CTL_POWER_INFO savedCtlPowerInfo;
A_UINT32 checkSumLengthLib=0x400; //default to 16k
A_UINT32 eepromSizeLib=0;
extern void getAR6000Struct(
A_UINT32 devNum,
void **ppReturnStruct, //return ptr to struct asked for
A_UINT32 *pNumBytes //return the size of the structure
);
EEP_OFFSET_STRUCT eep3_2 = {
0xbf, //HDR_COUNTRY_CODE
0xc2, //HDR_MODE_DEVICE_INFO
0xc4, //HDR_ANTENNA_GAIN
0xc9, //HEADER_MAC_FEATURES
0xc5, //HDR_11A_COMMON
0xd0, //HDR_11B_COMMON
0xda, //HDR_11G_COMMON
0xe4, //HDR_CTL
0xee, //HDR_11A_SPECIFIC
0xec, //HDR_11B_SPECIFIC
0xed, //HDR_11G_SPECIFIC
0x100, //GROUP1_11A_FREQ_PIERS
0x105, //GROUP2_11A_RAW_PWR
0x137, //GROUP3_11B_RAW_PWR
0x146, //GROUP4_11G_RAW_PWR
0x155, //GROUP5_11A_TRGT_PWR
0x165, //GROUP6_11B_TRGT_PWR
0x169, //GROUP7_11G_TRGT_PWR
0x16f, //GROUP8_CTL_INFO
};
EEP_OFFSET_STRUCT eep3_3 = {
0xbf, //HDR_COUNTRY_CODE
0xc2, //HDR_MODE_DEVICE_INFO
0xc3, //HDR_ANTENNA_GAIN
0xc9, //HEADER_MAC_FEATURES
0xd4, //HDR_11A_COMMON
0xf2, //HDR_11B_COMMON
0x10d, //HDR_11G_COMMON
0x128, //HDR_CTL
0xe0, //HDR_11A_SPECIFIC
0xfc, //HDR_11B_SPECIFIC
0x117, //HDR_11G_SPECIFIC
0x150, //GROUP1_11A_FREQ_PIERS
0x155, //GROUP2_11A_RAW_PWR
0x187, //GROUP3_11B_RAW_PWR
0x196, //GROUP4_11G_RAW_PWR
0x1a5, //GROUP5_11A_TRGT_PWR
0x1b5, //GROUP6_11B_TRGT_PWR
0x1b9, //GROUP7_11G_TRGT_PWR
0x1bf, //GROUP8_CTL_INFO
};
EEP_OFFSET_STRUCT *pOffsets = NULL;
/**************************************************************************
* mapPcdacTable - Create full pcdac table from limited table
*
* Given the limited EEPROM table, creates a full linear pcdac to power table
* by extrapolating the power for the intermediate pcdac values
*
* RETURNS: Fills in the full pcdac to power table
*/
void
mapPcdacTable
(
MDK_PCDACS_EEPROM *pSrcStruct, //limited input table
MDK_FULL_PCDAC_STRUCT *pPcdacStruct //pointer to table to complete
)
{
A_UINT16 *pPcdacValue;
A_INT16 *pPwrValue;
A_UINT16 i, j;
A_UINT16 numPcdacs = 0;
//create the pcdac values
for(i = PCDAC_START, j = 0; i <= PCDAC_STOP; i+= PCDAC_STEP, j++) {
numPcdacs++;
pPcdacStruct->PcdacValues[j] = i;
}
pPcdacStruct->numPcdacValues = numPcdacs;
pPcdacStruct->pcdacMin = pPcdacStruct->PcdacValues[0];
pPcdacStruct->pcdacMax = pPcdacStruct->PcdacValues[numPcdacs - 1];
pPcdacValue = pPcdacStruct->PcdacValues;
pPwrValue = pPcdacStruct->PwrValues;
//for each of the pcdac values, calculate the power
for(j = 0; j < pPcdacStruct->numPcdacValues; j++ ) {
*pPwrValue = getScaledPower(pPcdacStruct->channelValue, *pPcdacValue, pSrcStruct);
pPcdacValue++;
pPwrValue++;
}
return;
}
/**************************************************************************
* getScaledPower - Calculate power from pcdac values by extrapolation
*
* Either find the power value for the pcdac in the input table
* or extrapolate between 2 nearest pcdac and channel values to get the power
* Power returned is scaled to avoid use of floats
*
* RETURNS: scaled Power value for a given pcdac
*/
A_INT16
getScaledPower
(
A_UINT16 channel, //which channel, power is needed for
A_UINT16 pcdacValue, //which pcdac value, power is needed for
MDK_PCDACS_EEPROM *pSrcStruct //input structure to search
)
{
A_INT16 powerValue;
A_UINT16 lFreq, rFreq; //left and right frequency values
A_UINT16 llPcdac, ulPcdac; //lower and upper left pcdac values
A_UINT16 lrPcdac, urPcdac; //lower and upper right pcdac values
A_INT16 lPwr, uPwr; //lower and upper temp pwr values
A_INT16 lScaledPwr, rScaledPwr; //left and right scaled power
//if value pcdac is part of the input set then can return
if(findValueInList(channel, pcdacValue, pSrcStruct, &powerValue)){
//value was copied from srcStruct
return(powerValue);
}
//find nearest channel and pcdac value to extrapolate between
getLeftRightChannels(channel, pSrcStruct, &lFreq, &rFreq);
getLowerUpperPcdacs(pcdacValue, lFreq, pSrcStruct, &llPcdac, &ulPcdac);
getLowerUpperPcdacs(pcdacValue, rFreq, pSrcStruct, &lrPcdac, &urPcdac);
//get the power index for the upper and lower pcdac
findValueInList(lFreq, llPcdac, pSrcStruct, &lPwr);
findValueInList(lFreq, ulPcdac, pSrcStruct, &uPwr);
lScaledPwr = getInterpolatedValue( pcdacValue, llPcdac, ulPcdac, lPwr, uPwr, 0);
findValueInList(rFreq, lrPcdac, pSrcStruct, &lPwr);
findValueInList(rFreq, urPcdac, pSrcStruct, &uPwr);
rScaledPwr = getInterpolatedValue( pcdacValue, lrPcdac, urPcdac, lPwr, uPwr, 0);
//finally get the power for this pcdac
return(getInterpolatedValue( channel, lFreq, rFreq, lScaledPwr, rScaledPwr, 0));
}
/**************************************************************************
* findValueInList - Search for pcdac value for a given channel
*
* Search input table to see if already have a pcdac/power mapping for
* the given pcdac value at the given channel
*
* RETURNS: TRUE (and fills in power value) if found. FALSE otherwise
*/
A_BOOL
findValueInList
(
A_UINT16 channel, //which channel, power is needed for
A_UINT16 pcdacValue, //which pcdac value, power is needed for
MDK_PCDACS_EEPROM *pSrcStruct, //input structure to search
A_INT16 *powerValue //return power value found in src struct
)
{
MDK_DATA_PER_CHANNEL *pChannelData;
A_UINT16 *pPcdac;
A_UINT16 i, j;
pChannelData = pSrcStruct->pDataPerChannel;
for(i = 0; i < pSrcStruct->numChannels; i++ ) {
if (pChannelData->channelValue == channel) {
pPcdac = pChannelData->PcdacValues;
for(j = 0; j < pChannelData->numPcdacValues; j++ ) {
if (*pPcdac == pcdacValue) {
*powerValue = pChannelData->PwrValues[j];
return(TRUE);
}
pPcdac++;
}
}
pChannelData++;
}
return(FALSE);
}
/**************************************************************************
* getInterpolatedValue - Calculate Interpolated value
*
* Use relationship between left and right source points then apply to the target
* points to perform the interpolation, scale the return value as required by the
* input flag
*
* RETURNS: the interpolated value, scaled or otherwise
*/
A_UINT16 getInterpolatedValue
(
A_UINT16 source, //Input source value
A_UINT16 srcLeft, //Value lower than source
A_UINT16 srcRight, //value greater than source
A_UINT16 targetLeft, //lower target value
A_UINT16 targetRight, //upper target value
A_BOOL scaleUp
)
{
A_UINT16 returnValue;
A_UINT16 lRatio;
A_UINT16 scaleValue = SCALE;
//to get an accurate ratio, always scale, if return scale needed, then don't scale back down
if((targetLeft * targetRight) == 0) {
return(0);
}
if (scaleUp) {
scaleValue = 1;
}
if (abs(srcRight - srcLeft) > 0) {
//note the ratio always need to be scaled, since it will be a fraction
lRatio = (A_UINT16)((source - srcLeft)*SCALE / (srcRight - srcLeft));
returnValue = (A_UINT16)((lRatio*targetRight + (SCALE-lRatio)*targetLeft)/scaleValue);
}
else {
returnValue = (A_UINT16)(targetLeft*(scaleUp ? SCALE : 1));
}
return (returnValue);
}
/**************************************************************************
* getLowerUpperValues - Get 2 values closest to search value in list
*
* Given a search value and a list of values, find the upper and lower values
* closest to it.If the value is one of the values in the list, or is within
* a small delta of a value in the list then return the same upper
* and lower value. All arithmatic is scaled to avoid floating point.
*
* RETURNS: the upper and lower values
*/
void getLowerUpperValues
(
A_UINT16 value, //value to search for
A_UINT16 *pList, //ptr to the list to search
A_UINT16 listSize, //number of entries in list
A_UINT16 *pLowerValue, //return the lower value
A_UINT16 *pUpperValue //return the upper value
)
{
A_UINT16 i;
A_UINT16 listEndValue = *(pList + listSize - 1);
A_UINT32 target = value * SCALE;
//see if value is lower than the first value in the list
//if so return first value
if (target < (A_UINT32)(*pList * SCALE - DELTA)) {
*pLowerValue = *pList;
*pUpperValue = *pList;
return;
}
//see if value is greater than last value in list
//if so return last value
if (target > (A_UINT32)(listEndValue * SCALE + DELTA)) {
*pLowerValue = listEndValue;
*pUpperValue = listEndValue;
return;
}
//look for value being near or between 2 values in list
for(i = 0; i < listSize; 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 (abs(pList[i]*SCALE - target) < DELTA) {
*pLowerValue = pList[i];
*pUpperValue = pList[i];
return;
}
//look for value being between current value and next value
//if so return these 2 values
if (target < (A_UINT32)(pList[i + 1]*SCALE - DELTA)) {
*pLowerValue = pList[i];
*pUpperValue = pList[i + 1];
return;
}
}
}
/**************************************************************************
* getLeftRightChannels - Get lower and upper channels from source struct.
*
* As above function, except pulls the channel list from the input struct
*
* RETURNS: the upper and lower channel values
*/
void getLeftRightChannels
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -