*feature: add new physical layer frequency estimation API.

This commit is contained in:
Gatsby Van
2024-01-24 11:02:46 +08:00
parent 481ab2d5c5
commit 802772ad15
2 changed files with 112 additions and 6 deletions
@@ -759,6 +759,59 @@ uint32_t Phy_GetTimeComp(L1_FRAME_TYPE frameType)
} }
} }
/*****************************************************************************/
/**
* @brief Get frequency estimation of last valid frame.
*
* @param instPtr a pointer to physical instance
*
* @return frequency estimation
*
******************************************************************************/
double Phy_GetFreqEst(PHY_INST *instPtr)
{
ASSERT(instPtr != NULL);
uint32_t coarseReg, fineReg, estAbs;
uint8_t acqFreqIdx;
int8_t syncFreqIdx;
L1_FRAME_TYPE frameType;
double coarse, fine;
frameType = Phy_GetLastRecvFrameType(instPtr);
if (frameType > L1_1M2BPS_5MS_FRAME || frameType <= L1_NONE_FRAME)
{
return INFINITY; // FIXME
}
coarseReg = PhyRead(instPtr, COASE_FREQEST);
acqFreqIdx = (coarseReg & COASE_FREQEST_ACQ_MASK) >> COASE_FREQEST_ACQ_SHIFT;
syncFreqIdx = (coarseReg & COASE_FREQEST_SYNC_MASK) >> COASE_FREQEST_SYNC_SHIFT;
fineReg = PhyRead(instPtr, FINE_FREQEST);
estAbs = fineReg & FINE_FREQEST_VAL_MASK;
if (frameType >= L1_200KBPS_5MS_FRAME)
{
// 1.5M Rc
coarse = (double)(80 - acqFreqIdx) * (31.25e3 / 4);
coarse += (double)syncFreqIdx * 1.5e6 / 64 / 128;
fine = 12e6/2048*((double)estAbs)/8192.0;
}
else
{
// 12M Rc
coarse = (double)(8 - acqFreqIdx) * (250e3 / 4);
coarse += (double)syncFreqIdx * 12e6 / 64 / 128;
fine = 48e6/2048*((double)estAbs)/8192.0;
}
fine = ((fineReg & FINE_FREQEST_SIGN_MASK) == FINE_FREQEST_SIGN_NEG) ?
-fine : fine;
return (coarse + fine);
}
/*****************************************************************************/ /*****************************************************************************/
/** /**
* @brief Get coarse frequency estimation of last valid frame. * @brief Get coarse frequency estimation of last valid frame.
@@ -778,9 +831,9 @@ double Phy_GetCoarseFreqEst(PHY_INST *instPtr)
double freqEst; double freqEst;
frameType = Phy_GetLastRecvFrameType(instPtr); frameType = Phy_GetLastRecvFrameType(instPtr);
if (frameType > L1_1M2BPS_5MS_FRAME || frameType == L1_NONE_FRAME) if (frameType > L1_1M2BPS_5MS_FRAME || frameType <= L1_NONE_FRAME)
{ {
return INFINITY; // FIXME: return INFINITY; // FIXME
} }
regValue = PhyRead(instPtr, COASE_FREQEST); regValue = PhyRead(instPtr, COASE_FREQEST);
acqFreqIdx = (regValue & COASE_FREQEST_ACQ_MASK) >> COASE_FREQEST_ACQ_SHIFT; acqFreqIdx = (regValue & COASE_FREQEST_ACQ_MASK) >> COASE_FREQEST_ACQ_SHIFT;
@@ -801,6 +854,43 @@ double Phy_GetCoarseFreqEst(PHY_INST *instPtr)
return freqEst; return freqEst;
} }
/*****************************************************************************/
/**
* @brief Get fine frequency estimation of last valid frame.
*
* @param instPtr a pointer to physical instance
*
* @return frequency estimation
*
******************************************************************************/
double Phy_GetFineFreqEst(PHY_INST *instPtr)
{
uint32_t regValue, estAbs;
double freqEst;
L1_FRAME_TYPE frameType;
frameType = Phy_GetLastRecvFrameType(instPtr);
if (frameType > L1_1M2BPS_5MS_FRAME || frameType <= L1_NONE_FRAME)
{
return INFINITY; // FIXME
}
regValue = PhyRead(instPtr, FINE_FREQEST);
estAbs = regValue & FINE_FREQEST_VAL_MASK;
if (frameType >= L1_200KBPS_5MS_FRAME)
{
// 1.5M Rc
freqEst = 12e6/2048*((double)estAbs)/8192.0;
}
else
{
// 12M Rc
freqEst = 48e6/2048*((double)estAbs)/8192.0;
}
freqEst = ((regValue & FINE_FREQEST_SIGN_MASK) == FINE_FREQEST_SIGN_NEG) ?
-freqEst : freqEst;
return freqEst;
}
/*****************************************************************************/ /*****************************************************************************/
/** /**
* @brief Setup a frequency hopping pattern. * @brief Setup a frequency hopping pattern.
@@ -229,15 +229,31 @@
#define COASE_FREQEST_ACQ_MASK 0x000000FFU #define COASE_FREQEST_ACQ_MASK 0x000000FFU
#define COASE_FREQEST_SYNC_SHIFT 8 #define COASE_FREQEST_SYNC_SHIFT 8
#define COASE_FREQEST_SYNC_WIDTH 8 #define COASE_FREQEST_SYNC_WIDTH 8
#define COASE_FREQEST_SYNC_MASK 0x000FF00U #define COASE_FREQEST_SYNC_MASK 0x0000FF00U
#define COASE_TYPE_SHIFT 16
#define COASE_TYPE_WIDTH 8
#define COASE_TYPE_MASK 0x00FF0000U
#define COASE_TYPE_2KBPS_20MS 0x00010000U
#define COASE_TYPE_2KBPS_100MS 0x00020000U
#define COASE_TYPE_10KBPS_10MS 0x00030000U
#define COASE_TYPE_10KBPS_20MS 0x00040000U
#define COASE_TYPE_40KBPS_20MS 0x00050000U
#define COASE_TYPE_40KBPS_10MS 0x00060000U
#define COASE_TYPE_200KBPS_5MS 0x00070000U
#define COASE_TYPE_1M2BPS_5MS 0x00080000U
/** /**
* Register: FINE_FREQEST * Register: FINE_FREQEST
*/ */
#define FINE_FREQEST 0x00000040U #define FINE_FREQEST 0x00000040U
#define FINE_FREQEST_SHIFT 0 #define FINE_FREQEST_VAL_SHIFT 0
#define FINE_FREQEST_WIDTH 32 #define FINE_FREQEST_VAL_WIDTH 24
#define FINE_FREQEST_MASK 0xFFFFFFFFU #define FINE_FREQEST_VAL_MASK 0x00FFFFFFU
#define FINE_FREQEST_SIGN_SHIFT 24
#define FINE_FREQEST_SIGN_WIDTH 8
#define FINE_FREQEST_SIGN_MASK 0xFF000000U
#define FINE_FREQEST_SIGN_POS 0x00000000U
#define FINE_FREQEST_SIGN_NEG 0x01000000U
/** /**
* Register: BEAM_SELECT * Register: BEAM_SELECT