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

📄 tda8961.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的设备库的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *  Copyright (c) 1999 by TriMedia Technologies.
 *
 *  +-------------------------------------------------------------------+
 *  | This software  is furnished under a license  and may only be used |
 *  | and copied in accordance with the terms  and conditions of such a |
 *  | license  and with  the inclusion of this  copyright notice.  This |
 *  | software or any other copies of this software may not be provided |
 *  | or otherwise  made available  to any other person.  The ownership |
 *  | and title of this software is not transferred.                    |
 *  |                                                                   |
 *  | The information  in this software  is subject  to change  without |
 *  | any  prior notice  and should not be construed as a commitment by |
 *  | TriMedia Technologies.                                            |
 *  |                                                                   |
 *  | This  code  and  information  is  provided  "as is"  without  any |
 *  | warranty of any kind,  either expressed or implied, including but |
 *  | not limited  to the implied warranties  of merchantability and/or |
 *  | fitness for any particular purpose.                               |
 *  +-------------------------------------------------------------------+
 *
 *
 *  Module name              : tda8961.c  1.7
 *
 *  Last update              : 18:43:48  -  00/11/09
 *
 *  Description              :
 *
 */

#include "tda8961.h"

#include <tmlib/dprintf.h>
#include <tmlib/tmtypes.h>
#include <tm1/tmAssert.h>
#include <tm1/tmIIC.h>
#include <tm1/tmProcessor.h>

#define  N_VSB_CNTR_REGS        54
#define  N_VSB_STAT_REGS        13

#define CHECK_OUTPUT_ATSC(x, y) if(vsbStatus->outputMode != omAtsc) {x = tda8961DigDemInit(unitID); y;}

typedef struct
{
    UInt32                  iicAddress;
    UInt8                   vsbIICTable[N_VSB_CNTR_REGS];
    tda8961OutputMode_t     outputMode;
    Bool                    iicWorkaround;
    Int                     clusterPositions[4];
}tda8961Status_t, *ptda8961Status_t;

static UInt8 vsb2ControlDefault[N_VSB_CNTR_REGS] = {
    0x00, 0x00, 0x00, 0x00, 0x00,                       /* General Settings */
    0x01,                                               /* SRC */
    0x20,                                               /* AGC */
    0x0E,                                               /* AGC/Carrier recovery */
    0x04, 0x00, 0x00,                                   /* Timing recovery */
    0x00, 0x00, 0x44,0x24,0x00,                         /* Sync Enhancer */
    0x80,                                               /* Sync recovery */
    0x02, 0x80, 0x00, 0xCA, 0xFC, 0x96, 0x66, 0x22,     /* EQ/Correlator */
    0x2F, 0x00, 0xFC, 0x96, 0x66, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x60,
    0x00, 0x00, 0x00, 0x00,
    0x02, 0x00,                                         /* NTSC cc filter */
    0x04,                                               /* Trellis decoder */
    0x38, 0x00, 0x00, 0x00,                             /* Transport stream IF */
    0x00,                                               /* Diagnostics */
    0x00                                                /* Debug */
};

static Int             eqTaps[148];
static tda8961Status_t statusArray[4];

static Int                    clusterTaps[32 * 4];
static tsaTvDigDemEqCluster_t staticClusterArray[4] =
{
{0, 32, &clusterTaps[0]},
{0, 32, &clusterTaps[32]},
{0, 32, &clusterTaps[64]},
{0, 32, &clusterTaps[96]}
};

static tmLibdevErr_t writeRegisters(ptda8961Status_t vsbStatus, Int n);

/******************************************************************************/
static tmLibdevErr_t writeRegisters(ptda8961Status_t vsbStatus, Int n)
{
    iicRequest_t  req;
    tmLibdevErr_t err;
    Int           iicInstance;

    DP(("tda8961 writeRegisters\n"));

    /* TM1100 1.2 cannot do writing of 5, 9, 13, ..., 4n+1, ... bytes */
    if (vsbStatus->iicWorkaround)
    {
        if ((n - ((n >> 2) << 2)) == 1)
            n += 1;
    }

    req.address              = vsbStatus->iicAddress;
    req.byteCount            = n;
    req.direction            = IIC_WRITE;
    req.type                 = IIC_SIMPLE;
    req.data                 = vsbStatus->vsbIICTable;
    req.numRetries           = 1;
    req.waitBeforeRetry      = 200;
    req.mode                 = IIC_Synchronous_By_Polling;
    req.completion_function  = Null;

    err = iicOpen(&iicInstance);
    if (err != TMLIBDEV_OK)
        return err;

    err = iicDispatch(iicInstance, &req);
    if (err != TMLIBDEV_OK)
        return err;

    err = iicClose(iicInstance);
    if (err != TMLIBDEV_OK)
        return err;

    return TMLIBDEV_OK;
}

/******************************************************************************/
extern tmLibdevErr_t tda8961Init(UInt32 unitID, ptda8961Param_t params)
{
    tmLibdevErr_t       err;
    ptda8961Status_t    vsbStatus = &statusArray[unitID];
    Int                 i;
    pprocCapabilities_t procCaps;

    tmAssert(params, TMLIBDEV_ERR_NULL_PARAMETER);

    err = procGetCapabilities(&procCaps);
    if (err)
    {
        DP(("tda8961Init: Error %d in line %d\n", err, __LINE__));
        return err;
    }

    vsbStatus->outputMode       = omNoneSelected;
    vsbStatus->iicWorkaround    = True;

    if ((procCaps->deviceID == PROC_DEVICE_TM1100) &&
        (procCaps->revisionID >= PROC_REVISION_1_3))
    {
        vsbStatus->iicWorkaround = False;
    } 

    vsbStatus->iicAddress  = params->iicAddress;
    for (i = 0; i < N_VSB_CNTR_REGS; i++)
        vsbStatus->vsbIICTable[i] = vsb2ControlDefault[i];

    /* write default values into registers */
    err = writeRegisters(vsbStatus, N_VSB_CNTR_REGS);
    if (err != TMLIBDEV_OK)
        return err;

    vsbStatus->clusterPositions[0] = 0;
    vsbStatus->clusterPositions[1] = 32;
    vsbStatus->clusterPositions[2] = 64;
    vsbStatus->clusterPositions[3] = 96;

    return TMLIBDEV_OK;
}

/******************************************************************************/
extern tmLibdevErr_t tda8961Term(UInt32 unitID)
{
    return TMLIBDEV_OK;
}

/******************************************************************************/
extern tmLibdevErr_t tda8961DigDemInit(UInt32 unitID)
{
    ptda8961Status_t    vsbStatus = &statusArray[unitID];
    tmLibdevErr_t       err;

    vsbStatus->vsbIICTable[0x30] |= 0x10;
    vsbStatus->vsbIICTable[0x31]  = 0x00;

    /* write changed values into registers */
    err = writeRegisters(vsbStatus, 0x32);
    if (err != TMLIBDEV_OK)
        return err;

    vsbStatus->outputMode = omAtsc;

    return TMLIBDEV_OK;
}

/******************************************************************************/
extern tmLibdevErr_t tda8961Start(UInt32 unitID)
{
    tmLibdevErr_t    err;
    ptda8961Status_t vsbStatus = &statusArray[unitID];

    DP(("tda8961Start\n"));

    CHECK_OUTPUT_ATSC(err, return err);

    err = writeRegisters(vsbStatus, N_VSB_CNTR_REGS);
    if (err != TMLIBDEV_OK)
        return err;

    return TMLIBDEV_OK;
}

/******************************************************************************/
extern tmLibdevErr_t tda8961Stop(UInt32 unitID)
{
    return TMLIBDEV_OK;
}

/******************************************************************************/
extern tmLibdevErr_t tda8961GetStatus(UInt32 unitID, ptsaTvDigDemStatus_t status)
{
    iicRequest_t     req;
    tmLibdevErr_t    err;
    Int              iicInstance;
    UInt8            iica[6];
    ptda8961Status_t vsbStatus = &statusArray[unitID];
    
    DP(("tda8961GetStatus\n"));

    CHECK_OUTPUT_ATSC(err, return err);

    req.address              = vsbStatus->iicAddress;
    req.byteCount            = 6;
    req.direction            = IIC_READ;
    req.type                 = IIC_SIMPLE;
    req.data                 = iica;
    req.numRetries           = 1;
    req.waitBeforeRetry      = 200;
    req.mode                 = IIC_Synchronous_By_Polling;
    req.completion_function  = Null;

    err = iicOpen(&iicInstance);
    if (err != TMLIBDEV_OK)
        return err;

    err = iicDispatch(iicInstance, &req);
    if (err != TMLIBDEV_OK)
        return err;

    err = iicClose(iicInstance);
    if (err != TMLIBDEV_OK)
        return err;

    status->lockIndicator   = (iica[0] & 0x04)?True:False;
    status->eqLockIndicator = (iica[0] & 0x02)?True:False;
    status->mse             = ((UInt) iica[4]) << 8;
    status->mse            |= iica[5];

    return TMLIBDEV_OK;
}

/******************************************************************************/
extern tmLibdevErr_t tda8961GetTapsAndStatus(UInt32 unitID, ptsaTvDigDemStatus_t status)
{
    iicRequest_t     req;
    tmLibdevErr_t    err;
    Int              iicInstance;
    UInt8            iica[154];
    Int              i;
    ptda8961Status_t vsbStatus = &statusArray[unitID];

    CHECK_OUTPUT_ATSC(err, return err);

    /* set control register to enable taps read */
    vsbStatus->vsbIICTable[2] |= 0x02;
    err = writeRegisters(vsbStatus, 3);
    if (err != TMLIBDEV_OK)
    {
        vsbStatus->vsbIICTable[2] &= 0xfd;
        return err;
    }

    req.address              = vsbStatus->iicAddress;
    req.byteCount            = 148 + 7;
    req.direction            = IIC_READ;
    req.type                 = IIC_SIMPLE;
    req.data                 = iica;
    req.numRetries           = 1;
    req.waitBeforeRetry      = 200;
    req.mode                 = IIC_Synchronous_By_Polling;
    req.completion_function  = Null;

    err = iicOpen(&iicInstance);
    if (err != TMLIBDEV_OK)
        return err;

    err = iicDispatch(iicInstance, &req);
    if (err != TMLIBDEV_OK)
        return err;

    err = iicClose(iicInstance);
    if (err != TMLIBDEV_OK)
        return err;

    status->lockIndicator   = (iica[0] & 0x04)?True:False;
    status->eqLockIndicator = (iica[0] & 0x02)?True:False;
    status->mse             = ((UInt) iica[4]) << 8;
    status->mse            |= iica[5];

    for (i = 0; i < 148; i++)
        eqTaps[i] = (Int8) iica[7 + i];

    status->numEqTaps = 148;
    status->eqTaps    = eqTaps;

    /* set control register to disable taps read */
    vsbStatus->vsbIICTable[2] &= 0xfd;
    err = writeRegisters(vsbStatus, 3);
    if (err != TMLIBDEV_OK)
        return err;

    return TMLIBDEV_OK;
}

/******************************************************************************/
extern tmLibdevErr_t tda8961GetOffset(UInt32 unitID, Int *offset)
{
    iicRequest_t     req;
    tmLibdevErr_t    err;
    Int              iicInstance;
    UInt8            iica[2];
    ptda8961Status_t vsbStatus = &statusArray[unitID];

    CHECK_OUTPUT_ATSC(err, return err);

    req.address              = vsbStatus->iicAddress;
    req.byteCount            = 2;
    req.direction            = IIC_READ;
    req.type                 = IIC_SIMPLE;
    req.data                 = iica;
    req.numRetries           = 1;
    req.waitBeforeRetry      = 200;
    req.mode                 = IIC_Synchronous_By_Polling;
    req.completion_function  = Null;

    err = iicOpen(&iicInstance);
    if (err != TMLIBDEV_OK)
        return err;

    err = iicDispatch(iicInstance, &req);
    if (err != TMLIBDEV_OK)
        return err;

    err = iicClose(iicInstance);
    if (err != TMLIBDEV_OK)
        return err;

    *offset = (Int) (1250 * (Int8) iica[1]);

    return TMLIBDEV_OK;
}

/******************************************************************************/
extern tmLibdevErr_t tda8961GetClusters(UInt32 unitID, ptsaTvDigDemEqCluster_t *clusterArray)
{
    iicRequest_t     req;
    tmLibdevErr_t    err;
    Int              iicInstance;
    UInt8            iica[154];
    Int              i;
    ptda8961Status_t vsbStatus = &statusArray[unitID];

    tmAssert(clusterArray, TMLIBDEV_ERR_NULL_PARAMETER);

    CHECK_OUTPUT_ATSC(err, return err);

    /* set control register to enable cluster taps read */
    vsbStatus->vsbIICTable[2] |= 0x01;
    /* reset equalizer - HW problem workaround */
    vsbStatus->vsbIICTable[0] |= 0x08;
    err = writeRegisters(vsbStatus, 3);
    if (err != TMLIBDEV_OK)
    {
        vsbStatus->vsbIICTable[2] &= 0xfe;
        return err;
    }

    /* wait 90ms - HW problem workaround */
    microsleep(90000);

    req.address              = vsbStatus->iicAddress;
    req.byteCount            = 128 + 8;
    req.direction            = IIC_READ;
    req.type                 = IIC_SIMPLE;
    req.data                 = iica;

⌨️ 快捷键说明

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