📄 tmbsl10023.c
字号:
{
// Delete the previous buffer
free(psuPrevBer);
psuPrevBer = Null;
}
// Allocate a new buffer to store the BER values
psuPrevBer = (UInt32*) calloc(g10023Instance[demodUnit].sConfig.uBERwindow, sizeof(UInt32));
suWindowSize = g10023Instance[demodUnit].sConfig.uBERwindow;
suIndex = 0;
}
uMeanBer = *puBer;
// Calculate the mean value with a sliding window of N samples
for(i = 0; i<g10023Instance[demodUnit].sConfig.uBERwindow; i++)
{
uMeanBer += psuPrevBer[i];
}
uMeanBer -= psuPrevBer[suIndex];
psuPrevBer[suIndex] = *puBer;
suIndex++;
if(suIndex == g10023Instance[demodUnit].sConfig.uBERwindow)
suIndex = 0;
*puBer = uMeanBer/g10023Instance[demodUnit].sConfig.uBERwindow;
}
}
switch(uBerDepth & TDA10023_RSCFG_PRG_TBER_MSK)
{
case 0x00: // 262144
*puBer *= 545; // 100000000/(262144*7) = 54.5 (7 is the number of bits per symbol)
*puBer += 5;
*puBer /= 10;
break;
case 0x04: // 2097152
*puBer *= 681; // 100000000/(2097152*7) = 6.812
*puBer += 50;
*puBer /= 100;
break;
case 0x08: // 16777216
*puBer *= 851; // 100000000/(16777216*7) = 0.8515
*puBer += 500;
*puBer /= 1000;
break;
case 0x0c: // 134217728
*puBer *= 1064; // 100000000/(134217728*7) = 0.1064
*puBer += 5000;
*puBer /= 10000;
break;
}
}
else
{
// DVB mode
g10023Instance[demodUnit].systemFunc.SY_Read(g10023Instance[demodUnit].uDemodHwAdd,
TDA10023_BERLSB_IND, 3, puBerBuf);
*puBer = puBerBuf[2]<<16 | puBerBuf[1]<<8 | puBerBuf[0];
// read the BER depth
g10023Instance[demodUnit].systemFunc.SY_Read(g10023Instance[demodUnit].uDemodHwAdd,
TDA10023_FECDVBCFG1_IND, 1, &uBerDepth);
switch(uBerDepth & TDA10023_FECDVBCFG1_PVBER_MSK)
{
case 0x00: // 1,00E+05
*puBer *= 1000;
break;
case 0x40: // 1,00E+06
*puBer *= 100;
break;
case 0x80: // 1,00E+07
*puBer *= 10;
break;
case 0xc0: // 1,00E+08
break;
}
}
return TM_OK;
}
//-----------------------------------------------------------------------------
// FUNCTION: tmbsl10023GetSNR
//
// DESCRIPTION: this function calculate the signal noise ratio in dB
//
// RETURN: TMBSL_ERR_DEMOD_BAD_UNIT_NUMBER
// TMBSL_ERR_DEMOD_NOT_INITIALIZED
// TM_OK
//
// NOTES: TBD
//-----------------------------------------------------------------------------
//
tmErrorCode_t
tmbsl10023GetSNR (
tmUnitSelect_t demodUnit, // I: Demod unit number
Int8 *pbSNR // O: SNR
)
{
float fSNR, fMSE;
UInt32 uCounter, uMSE;
//----------------------
// test input parameters
//----------------------
// test the instance number
if (demodUnit > TDA10023_MAX_UNITS)
return TMBSL_ERR_DEMOD_BAD_UNIT_NUMBER;
// test the object
if (g10023Instance[demodUnit].sApiFlags.iInit == False)
return TMBSL_ERR_DEMOD_NOT_INITIALIZED;
//----------------------
// Implementation
//----------------------
fMSE = (float)0;
for (uCounter = 0; uCounter < 10; uCounter++)
{
// average value of the MSE on 10 values
g10023Instance[demodUnit].systemFunc.SY_Read(g10023Instance[demodUnit].uDemodHwAdd,
TDA10023_MSE_IND, 1, &uMSE);
fMSE += (float)uMSE;
}
fMSE /= (float)uCounter;
// calculate the SNR regarding to the modulation
switch (g10023Instance[demodUnit].sCurrentChannel.eMOD)
{
case tmhalFEModulationQam16:
fSNR = (float)((195.0/(0.32*fMSE + 1.38)) + 10.0);
break;
case tmhalFEModulationQam32:
fSNR = (float)((215.0/(0.40*fMSE + 5.0)) + 13.5);
break;
case tmhalFEModulationQam64:
fSNR = (float)((210.0/(0.40*fMSE + 5.0)) + 12.5);
break;
case tmhalFEModulationQam128:
fSNR = (float)((185.0/(0.38*fMSE + 4.0)) + 13.8);
break;
case tmhalFEModulationQam256:
fSNR = (float)((180.0/(1.00*fMSE + 0.4)) + 20.3);
break;
default:
return TMBSL_ERR_DEMOD_NOT_SUPPORTED;
}
//d_prinft( "-%d- \n",(unsigned long)fMSE);
//d_prinft( "-%d- \n",(unsigned long)fSNR);
// update value
*pbSNR = (Int8)fSNR;
//d_prinft( "-%d- \n",(unsigned char)*pbSNR);
return TM_OK;
}
//-----------------------------------------------------------------------------
// FUNCTION: tmbsl10023GetLVL
//
// DESCRIPTION: this function reads an estimated level in dBm.
//
// RETURN: TMBSL_ERR_DEMOD_NOT_SUPPORTED
//
// NOTES: not implemented
//-----------------------------------------------------------------------------
//
tmErrorCode_t
tmbsl10023GetLVL (
tmUnitSelect_t demodUnit, // I: Demod unit number
Int8* pbLVL // O: Level in unit of dBm
)
{
unsigned long lvl,TUNagc,IFagc;
//----------------------
// test input parameters
//----------------------
// test the instance number
if (demodUnit > TDA10023_MAX_UNITS)
return TMBSL_ERR_DEMOD_BAD_UNIT_NUMBER;
// test the object
if (g10023Instance[demodUnit].sApiFlags.iInit == False)
return TMBSL_ERR_DEMOD_NOT_INITIALIZED;
//----------------------
// Implementation
//----------------------
//read the TUNAGC and IFAGC for judge of SIGNAL LVL;
g10023Instance[demodUnit].systemFunc.SY_Read(g10023Instance[demodUnit].uDemodHwAdd,
TDA10023_AGCTUN_IND, 1, &TUNagc);
/* g10023Instance[demodUnit].systemFunc.SY_Read(g10023Instance[demodUnit].uDemodHwAdd,
TDA10023_AGCIF_IND, 1, &IFagc);
*/
//----------------------------
//Get the final signal level from the AGC value
//----------------------------
//set lvl
*pbLVL = (unsigned char)TUNagc;
//*pbls = IFagc;
return TM_OK;
//return TMBSL_ERR_DEMOD_NOT_SUPPORTED;
}
//-----------------------------------------------------------------------------
// FUNCTION: tmbsl10023GetAFC
//
// DESCRIPTION: this function calculate the AFC in hertz
//
// RETURN: TMBSL_ERR_DEMOD_BAD_UNIT_NUMBER
// TMBSL_ERR_DEMOD_NOT_INITIALIZED
// TM_OK
//
// NOTES:
//
//-----------------------------------------------------------------------------
//
tmErrorCode_t
tmbsl10023GetAFC (
tmUnitSelect_t demodUnit, // I: Demod unit number
Int32 *plAFC // O: AFC
)
{
//----------------------
// test input parameters
//----------------------
// test the instance number
if (demodUnit > TDA10023_MAX_UNITS)
return TMBSL_ERR_DEMOD_BAD_UNIT_NUMBER;
// test the object
if (g10023Instance[demodUnit].sApiFlags.iInit == False)
return TMBSL_ERR_DEMOD_NOT_INITIALIZED;
//----------------------
// Implementation
//----------------------
Tda10023ReadAFC(&g10023Instance[demodUnit], plAFC);
return TM_OK;
}
//-----------------------------------------------------------------------------
// FUNCTION: tmbsl10023GetACC
//
// DESCRIPTION: the function calculates symbol frequency error in ppm
//
// RETURN: TMBSL_ERR_DEMOD_BAD_UNIT_NUMBER
// TMBSL_ERR_DEMOD_NOT_INITIALIZED
// TM_OK
//
// NOTES: formula:
// if DYN= 0: CKoffset*10e6/2^19 ppm
// if DYN= 1: CKoffset*10e6/2^18 ppm
//
//-----------------------------------------------------------------------------
//
tmErrorCode_t
tmbsl10023GetACC (
tmUnitSelect_t demodUnit, // I: Demod unit number
Int32 *plACC // O: frequency error in ppm
)
{
//----------------------
// test input parameters
//----------------------
// test the instance number
if (demodUnit > TDA10023_MAX_UNITS)
return TMBSL_ERR_DEMOD_BAD_UNIT_NUMBER;
// test the object
if (g10023Instance[demodUnit].sApiFlags.iInit == False)
return TMBSL_ERR_DEMOD_NOT_INITIALIZED;
//----------------------
// Implementation
//----------------------
g10023Instance[demodUnit].systemFunc.SY_Read(
g10023Instance[demodUnit].uDemodHwAdd, TDA10023_CKOFF_IND, 1, plACC);
// signed value if needed -> 8 bits
if (*plACC & 0x80)
*plACC |= 0xFFFFFF00;
// calculate the error in ppm - assumed +/-480ppm for DYN
*plACC *= 1000000;
*plACC /= 262144; // 262144 = 2^18
// add constant use in the algo to extend the clk offset range
// TBD
*plACC += g10023Instance[demodUnit].lClkOffCst;
return TM_OK;
}
//-----------------------------------------------------------------------------
// FUNCTION: tmbsl10023GetUBK
//
// DESCRIPTION: the function reads the uncorrected block number.
//
// RETURN: TMBSL_ERR_DEMOD_BAD_UNIT_NUMBER
// TMBSL_ERR_DEMOD_NOT_INITIALIZED
// TM_OK
// TM_FALSE
//
// NOTES:
//-----------------------------------------------------------------------------
//
tmErrorCode_t
tmbsl10023GetUBK (
tmUnitSelect_t demodUnit, // I: Demod unit number
UInt32 *puUBK // O: Uncor
)
{
UInt32 puBytes[4];
//----------------------
// test input parameters
//----------------------
// test the instance number
if (demodUnit > TDA10023_MAX_UNITS)
return TMBSL_ERR_DEMOD_BAD_UNIT_NUMBER;
// test the object
if (g10023Instance[demodUnit].sApiFlags.iInit == False)
return TMBSL_ERR_DEMOD_NOT_INITIALIZED;
//----------------------
// Implementation
//----------------------
if(g10023Instance[demodUnit].sConfig.bModeDvbMcns)
{
// MCNS mode
g10023Instance[demodUnit].systemFunc.SY_Read(
g10023Instance[demodUnit].uDemodHwAdd,
TDA10023_CPT_RSB_UNCOR1_IND, 4, puBytes);
*puUBK = (puBytes[3]<<24) | (puBytes[2]<<16) | (puBytes[1]<<8) | puBytes[0];
// reset the counter is needed if there are uncors
if (*puUBK)
{
g10023Instance[demodUnit].systemFunc.SY_WriteBit(
g10023Instance[demodUnit].uDemodHwAdd,
TDA10023_RSCFG_IND, TDA10023_RSCFG_CLB_CPT_RSB_BIT, 0);
g10023Instance[demodUnit].systemFunc.SY_WriteBit(
g10023Instance[demodUnit].uDemodHwAdd,
TDA10023_RSCFG_IND, TDA10023_RSCFG_CLB_CPT_RSB_BIT, TDA10023_RSCFG_CLB_CPT_RSB_BIT);
}
}
else
{
// DVB mode
g10023Instance[demodUnit].systemFunc.SY_Read(
g10023Instance[demodUnit].uDemodHwAdd,
TDA10023_CPT_TSP_UNCOR1_IND, 4, puBytes);
*puUBK = (puBytes[3]<<24) | (puBytes[2]<<16) | (puBytes[1]<<8) | puBytes[0];
// reset the counter is needed if there are uncors
if (*puUBK)
{
g10023Instance[demodUnit].systemFunc.SY_WriteBit(
g10023Instance[demodUnit].uDemodHwAdd,
TDA10023_FECDVBCFG1_IND, TDA10023_FECDVBCFG1_CLB_CPT_TSP_BIT, 0);
g10023Instance[demodUnit].systemFunc.SY_WriteBit(
g10023Instance[demodUnit].uDemodHwAdd,
TDA10023_FECDVBCFG1_IND, TDA10023_FECDVBCFG1_CLB_CPT_TSP_BIT, TDA10023_FECDVBCFG1_CLB_CPT_TSP_BIT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -