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

📄 tmbsl10023.c

📁 三星一体化数字高频头DNQS221PH261A驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// NOTES:       
//-----------------------------------------------------------------------------
//
tmErrorCode_t
tmbsl10023SetMod (
    tmUnitSelect_t         demodUnit,    //  I: Demod unit number
    tmhalFEModulation_t    eMOD          //  I: Modulation type
)
{
    UInt32 uMod;

    SEND_TRACEFCT1(DEBUG_SETMOD_ID, 0);

    //----------------------
    // 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;

    // test the parameter value
    if (eMOD >= tmhalFEModulationMax)
        return TMBSL_ERR_DEMOD_BAD_PARAMETER;

    // !!!! TO BE REMOVED !!!!
    if (eMOD == tmhalFEModulationAuto)
        return TMBSL_ERR_DEMOD_BAD_PARAMETER;

    // In MCNS mode, only 64QAM and 256QAM are allowed
    if ((g10023Instance[demodUnit].sConfig.bModeDvbMcns) &&
        (eMOD != tmhalFEModulationAuto) &&
        (eMOD != tmhalFEModulationQam64) &&
        (eMOD != tmhalFEModulationQam256) )
        return TMBSL_ERR_DEMOD_BAD_PARAMETER;

    //----------------------
    // Implementation
    //----------------------
    switch (eMOD)
    {
    case tmhalFEModulationAuto:
        g10023Instance[demodUnit].sApiFlags.iAutoQam = True;
        uMod = 2;
        break;
    case tmhalFEModulationQam4:
        g10023Instance[demodUnit].sApiFlags.iAutoQam = False;
        uMod = 5;
        break;
    case tmhalFEModulationQam16:
        g10023Instance[demodUnit].sApiFlags.iAutoQam = False;
        uMod = 0;
        break;
    case tmhalFEModulationQam32:
        g10023Instance[demodUnit].sApiFlags.iAutoQam = False;
        uMod = 1;
        break;
    case tmhalFEModulationQam64:
        g10023Instance[demodUnit].sApiFlags.iAutoQam = False;
        uMod = 2;
        break;
    case tmhalFEModulationQam128:
        g10023Instance[demodUnit].sApiFlags.iAutoQam = False;
        uMod = 3;
        break;
    case tmhalFEModulationQam256:
        g10023Instance[demodUnit].sApiFlags.iAutoQam = False;
        uMod = 4;
        break;
    default:
        return TMBSL_ERR_DEMOD_BAD_PARAMETER;
    }

    // write the new modulation
    Tda10023WriteQAM(&g10023Instance[demodUnit], uMod);

    // update current config
    if (tmhalFEModulationAuto == eMOD)
        g10023Instance[demodUnit].sCurrentChannel.eMOD = tmhalFEModulationQam64;
    else
        g10023Instance[demodUnit].sCurrentChannel.eMOD = eMOD;

    // start algo
    g10023Instance[demodUnit].sApiFlags.iStartAlgo = True;

    return TM_OK;
}

//-----------------------------------------------------------------------------
// FUNCTION:    tmbsl10023GetMod
//
// DESCRIPTION: this function reads the current modulation
//
// RETURN:      TMBSL_ERR_DEMOD_BAD_UNIT_NUMBER
//              TMBSL_ERR_DEMOD_NOT_INITIALIZED    
//              TM_OK
//
// NOTES:       
//-----------------------------------------------------------------------------
//
tmErrorCode_t
tmbsl10023GetMod (
    tmUnitSelect_t        demodUnit,  //  I: Demod unit number
    tmhalFEModulation_t   *peMOD      //  O: Modulation type
)
{
    SEND_TRACEFCT2(DEBUG_GETMOD_ID, 0);

    //----------------------
    // 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
    //----------------------
    *peMOD = g10023Instance[demodUnit].sCurrentChannel.eMOD;

    return TM_OK;
}

//-----------------------------------------------------------------------------
// Status functions:
//-----------------------------------------------------------------------------
//

//-----------------------------------------------------------------------------
// FUNCTION:    tmbsl10023GetBER
//
// DESCRIPTION: this function reads the BER
//
// RETURN:      TMBSL_ERR_DEMOD_BAD_UNIT_NUMBER
//              TMBSL_ERR_DEMOD_NOT_INITIALIZED    
//              TM_OK
//
// NOTES:       the ber value read needs to be corrected due to the real
//              counter depth for 10e5
//
//-----------------------------------------------------------------------------
//
tmErrorCode_t
tmbsl10023GetBER (
    tmUnitSelect_t    demodUnit,     //  I: Demod unit number
    UInt32            *puBer         //  O: BER
)
{
    UInt32    puBerBuf[3], puUncorBuf[2], uBerDepth;
    UInt32    uUncor;
    UInt32 uMeanBer;
    static UInt32 *psuPrevBer = Null;
    static UInt32 suIndex=0;
    static UInt32 suWindowSize = 0;
    
    SEND_TRACEFCT2(DEBUG_GETBER_ID, 0);

    //----------------------
    // 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
        // Read RSBER
        g10023Instance[demodUnit].systemFunc.SY_Read(g10023Instance[demodUnit].uDemodHwAdd,
            TDA10023_RSBERLO_IND, 2, puBerBuf);

        // Read RSUNCOR
        g10023Instance[demodUnit].systemFunc.SY_Read(g10023Instance[demodUnit].uDemodHwAdd,
            TDA10023_RSUNCORLO_IND, 2, puUncorBuf);

        *puBer = puBerBuf[1]<<8 | puBerBuf[0];
        uUncor = puUncorBuf[1]<<8 | puUncorBuf[0];

        // We consider that there are 16 wrong bits per uncor
        *puBer += (uUncor*16);


        // read the BER depth
        g10023Instance[demodUnit].systemFunc.SY_Read(g10023Instance[demodUnit].uDemodHwAdd,
            TDA10023_RSCFG_IND, 1, &uBerDepth);

        if(((uBerDepth & TDA10023_RSCFG_PRG_TBER_MSK)>>2) == 0x01)
        {
            if(g10023Instance[demodUnit].sConfig.uBERwindow != 0)
            {
                UInt32 i;

                // If not already done, configure sliding window
                if(suWindowSize != g10023Instance[demodUnit].sConfig.uBERwindow)
                {
                    if(psuPrevBer != Null)
                    {
                        // 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
				//	divided by 10^8
            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
)
{
#ifndef NO_FLOAT
    float fSNR, fMSE;
#endif
    UInt32 uCounter, uMSE;
    
    SEND_TRACEFCT2(DEBUG_GETSNR_ID, 0);

    //----------------------
    // 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
    //----------------------
#ifndef NO_FLOAT
    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:

⌨️ 快捷键说明

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