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

📄 philips_iref.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的设备库的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
static Float                    __irefCPUClockFrequency;
static Bool                     __irefNeedToInitAD1847          = True;
static Bool                     __irefNeedAD1847Reset           = False;
static Bool                     __irefSampleRate                = 0.0;
static Bool                     __irefNeedToStartAi             = False;
static Bool                     __irefTMIsNot1S                 = False;

static Bool                     __irefAoInitialized             = False;
static Bool                     __irefAoRunning                 = False;
static Bool                     __irefAoNeedToConfigureOutput   = False;
static tmAudioPcmFormat_t       __irefAoCurrentPcmFormat        = apfNone;
static tmAudioAnalogAdapter_t   __irefAoOutput                  = aaaLineOutput1;
static Int                      __irefAoLGain                   = 0;
static Int                      __irefAoRGain                   = 0;

static Bool                     __irefAiInitialized             = False;
static Bool                     __irefAiRunning                 = False;
static Bool                     __irefAiNeedToConfigureInput    = False;
static tmAudioPcmFormat_t       __irefAiCurrentPcmFormat        = apfNone;
static tmAudioAnalogAdapter_t   __irefAiInput                   = aaaLineInput;
static Int                      __irefAiAd1847Input             = AD1847_SRC_LINE1;
static Int                      __irefAiLGain                   = 0;
static Int                      __irefAiRGain                   = 0;

/******************** iref_board_init *******************************
 *  The iref board comes up with peripherals reset.
 *  This function takes the board out of reset and leaves
 *  it in a good state.
 */
static tmLibdevErr_t iref_board_init(void)
{
    pprocCapabilities_t procCap;
    
    L1_DP(("iref_board_init\n"));
    TRY(procGetCapabilities(&procCap));

    /* get the clcok frequency -> this value is used to calculate audio and video
       frequencies */
    __irefCPUClockFrequency = (Float) procCap->cpuClockFrequency;
    L2_DP(("procCap->cpuClockFrequency = %d\n", __irefCPUClockFrequency));
    /* make sure VO clock is running at 27MHz! */
    MMIO(VO_CLOCK) = (UInt) (0.5 + 
          (1431655765.0 * VO_INIT_FREQ / __irefCPUClockFrequency));
    MMIO(VO_CTL) = 0x02700000;

    /*
     * IIC address 0x70 on IREF: 
     *  Bit 0 is Reset 
     *  Bit 1 is AC3_INIT (high)
     *  Bit 2 is st7545 AFE reset (low for reset) (formerly AC3 Mode) 
     *  Bit 3 is unused 
     *  Bit 4 is PWRDOWN  Audio: Low powers down ad1847 
     *  Bit 5 is CHMODE   Audio: Low resets ad1847 
     *  Bit 6 is MASTER Audio: selects ad1847 master/slave 
     *  Bit 7 is STANDBY  high to shut down 6 channel DAC
     */
    TRY(iicWriteReg(0x70, -1, 0xFE)); /* lower reset */
    MMIO(SSI_CTL) = 0x00040000;       /* V34IO2 goes high to stay on hook! */
    TRY(iicWriteReg(0x70, -1, 0xFF)); /* raise reset */
    saa7125Stop(vasNTSC);
    MMIO(VO_CLOCK) = 0;
    microsleep(100);                /* Without this, 1847 is not init'ed.  */

    /* check if processor is older then TM1 1.1S -> needed to set/get right audio frequencies */
    if ((procCap->deviceID == PROC_DEVICE_TM1000)
        && ((procCap->revisionID == PROC_REVISION_1_1)
        || (procCap->revisionID == PROC_REVISION_1_0)))
        __irefTMIsNot1S = True;

    return TMLIBDEV_OK;
}                /* end of iref_board_init() */

/******************** iref_board_detect *******************************
 * Returns TMLIBDEV_OK if the hardware appears to be a Philips IREF board.
 * This function reads subsystem ID and subsystem vendor ID from the boot
 * EEPROM and compares those to the values reserved for the Philips IREF board.
 */
static tmLibdevErr_t iref_board_detect(void)
{
    Int     line, error;
    UInt    d1, d2;
    UInt    boardID;    
    UInt    mfgID;      
    UInt8   eepromData[8];

    L1_DP(("iref_board_detect\n"));

    /* read boot EEPROM */
    for (line = 0; line < 8; line++)
    {
        error = iicReadReg(IIC_EEPROM_ADDRESS, line, &d1);
        if (error)
        {
            TRY(iicReadReg(IIC_EEPROM_ADDRESS, line, &d1));
        }
        error = iicReadReg(IIC_EEPROM_ADDRESS, line, &d2);
        if (error)
        {
            TRY(iicReadReg(IIC_EEPROM_ADDRESS, line, &d2));
        }
        eepromData[line] = d1;
    }

    /* get subsystem vendor ID */
    mfgID   = (eepromData[3] << 8) + eepromData[4];
    /* get subsystem ID */
    boardID = (eepromData[1] << 8) + eepromData[2];
    
    L2_DP(("Read in IIC: mfgID = %d / boardID = %d\n", mfgID, boardID ));

    /* Actually, why return TMLIBDEV_OK as on the contrary, it is not ! */
    /* zero should be returned. This is confusing */
    /* check if this is a Philips board */
    if (mfgID != BOARD_ID_PHILIPS_MFG_ID)
        return BOARD_ERR_UNKNOWN_BOARD;

    /* check if this is an IREF board */
    if (boardID == BOARD_ID_PHILIPS_TM1_IREF_SUBSYS_ID)
        return TMLIBDEV_OK;
   
    /* And then return */      
    return BOARD_ERR_UNKNOWN_BOARD;
}

static tmLibdevErr_t iref_board_activate(pcomponent_t comp)
{
    L1_DP(("iref_board_activate\n"));
    TRY(iref_board_detect());
    
    L2_DP(("Board recognized\n"));

    TRY(iref_board_init());
    
    /* This is time to register the component outputs. */
    /* This will be used by all the devices to check */
    /* whether they can work with this board or not */
    TRY(iref_board_register(comp));

    return TMLIBDEV_OK;
}


static tmLibdevErr_t iref_board_register(pcomponent_t comp)
{
    UInt32 ID = BOARD_VERSION_PHILIPS_TM1_IREF;
    
    L1_DP(("iref_board_register\n"));
    
    TRY(tsaBoardRegisterBoard(ID, "Philips IREF"));

    /* now register all the capabilities of the board : */
    /* AO, AI, VO, VI, SSI, etc */
    L2_DP(("Board registered\n"));

    TRY(tsaBoardRegisterAO(0,  &iref_ao));
    TRY(tsaBoardRegisterAI(0,  &iref_ai));
    TRY(tsaBoardRegisterVO(0,  &iref_vo));
    TRY(tsaBoardRegisterVI(0,  &iref_vi));
    TRY(tsaBoardRegisterSSI(0, &iref_afe));

    L2_DP(("Interfaces registered\n"));

    return TMLIBDEV_OK;
}

/**********************************************************
 *  This audio module supports stereo 16 bit
 *  and 6 channel modes.
 *  Support for 4 and 8 channel modes is non-existent.
 *  Lower quality modes probably return resonable errors.
 *
 */

/*******************************************************/
static tmLibdevErr_t iref_AO_init(pboardAOParam_t param)
{
    tmLibdevErr_t       rval = TMLIBDEV_OK;
    
    tmAssert(param, TMLIBDEV_ERR_NULL_PARAMETER);
    
    /* check audio output adapter settings */
    if (param->output & IREF_OUTPUT_AUDIO_ADAPTERS)
    {
        __irefAoOutput = param->output;
        if (param->output == aaaNone)
        {
            /* set default outputs */
            if (param->audioSubtypeFormat == apfFiveDotOne16)
            {
                __irefAoOutput = aaaLineOutput2;
            } 
            else
            {
                __irefAoOutput = aaaLineOutput1;
            }
        }
    }
    else
    {
        /* this should never happen since this is already checked in libdev layer */
        return AIO_ERR_UNSUPPORTED_OUTPUT;
    }

    if (__irefAiInitialized && (param->audioSubtypeFormat != __irefAiCurrentPcmFormat))
    {
        return (AIO_ERR_UNMATCHED_FORMATS);  /* we don't supposrt different formats at input
                                                and output */
    }

    /* check if the IREF board has been initialized in an other PCM format */
    if (__irefAoInitialized)
    {
        __irefAoInitialized = False;
        __irefAoCurrentPcmFormat = apfNone;
    }
    
    switch (param->audioSubtypeFormat)
    {
    case apfFiveDotOne16:
        /* initialization for 6 channel output (3 x CS4333) */
        /* check if the right output adapter has been set */
        if (__irefAoOutput != aaaLineOutput2)
        {
            return AIO_ERR_UNMATCHED_FORMATS;
        }
    
        /* reset the audio I/O peripherals */
        aoRESET();
        aiRESET();
        
        MMIO(AO_FREQ) = hertz2Control(param->sRate, 4, 32, 3);
        aoEnableSER_MASTER();
#ifdef __LITTLE_ENDIAN__
        aoEnableLITTLE_ENDIAN();
#else
        aoDisableLITTLE_ENDIAN();
#endif
        aoDisableSIGN_CONVERT();
        aoMsbFirst();                  /* MSB first */
        aoEnableWS_PULSE();            /* pulse mode because of bug 7064 */
        aoSampleRisingCLOCK_EDGE();    /* sample on rising edge */
        aoStartRisingEdgeWS();
        aoSetLEFTPOS(0);
        aoSetRIGHTPOS(16);
        aoSetTRANS_MODE(3);
        /* 3 * 32 * 4 = 384 fs */
        aoSetSFDIV(2);
        aoSetWSDIV(31);
        if (__irefTMIsNot1S) /* Workaround SCOPUS_BUG_ID_3013 */
            aoSetSCKDIV(5);
        else 
            aoSetSCKDIV(3);
        aoEnableBUF1_INTEN();
        aoEnableBUF2_INTEN();

        rval = ch6_init(param);
        if (rval == 0)
        {
            __irefAoInitialized         = True;
            __irefSampleRate            = param->sRate;
            __irefAoCurrentPcmFormat    = apfFiveDotOne16;
            strcpy(iref_ao.codecName, "triple CS4333"); /* 16 chars max */
        }
        
        /* set the size after ch6_init because this function changes this 
           MMIO register */
        aoSetSIZE(param->size * 3);
        
        break;
    case apfStereo16:
    case apfMono16:
        if (param->sRate > AD1847_MAX_SRATE)
        {
            return AIO_ERR_SRATE_TOO_HIGH;
        }
        if (param->sRate < AD1847_MIN_SRATE)
        {
            return AIO_ERR_SRATE_TOO_LOW;
        }
        
        /* check if the right output adapter has been set */
        if (__irefAoOutput != aaaLineOutput1)
        {
            return AIO_ERR_UNMATCHED_FORMATS;
        }
    
        if (__irefNeedToInitAD1847)
        {
            /* reset the audio I/O peripherals */
            aoRESET();
            aiRESET();
    
            /* only set the frequency for the DDS before initializing the AD1847 all other settings
             * will be changed by ad1847MasterInit().
             * Calculate and set frequency for DDS (512 fs). 
             * The frequencies for input and output are the same. */
            MMIO(AO_FREQ) = hertz2Control(param->sRate, 512, 1, 1);
            MMIO(AI_FREQ) = MMIO(AO_FREQ);
        
            rval = ad1847MasterInit((tmAudioPcmFormat_t)param->audioSubtypeFormat, 
                                    param->sRate);
            if (rval != TMLIBDEV_OK)
            {
                return rval;
            }
            __irefNeedToInitAD1847      = False;
            __irefSampleRate            = param->sRate;
        }
        
        /* initialization for AD 1847, 16 chars max */
        strcpy(iref_ao.codecName, "AD1847");

        /* setup audio out unit of the TriMedia */
        aoDisableSER_MASTER();
#ifdef __LITTLE_ENDIAN__
        aoEnableLITTLE_ENDIAN();
#else
        aoDisableLITTLE_ENDIAN();
#endif
        aoDisableSIGN_CONVERT();
        aoMsbFirst();                  /* MSB first */
        aoEnableWS_PULSE();            /* pulse mode because of bug 7064 */
        aoSampleFallingCLOCK_EDGE();    /* sample on falling edge */
        aoStartRisingEdgeWS();    /* frame starts on rising edge */
        aoSetLEFTPOS(16);
        aoSetRIGHTPOS(32);
        aoSetSIZE(param->size);
        if (param->audioSubtypeFormat == apfStereo16)
        {
            aoSetTRANS_MODE(3);
        }
        else
        {
            aoSetTRANS_MODE(2);
        }
        
        __irefAoCurrentPcmFormat = (tmAudioPcmFormat_t)param->audioSubtypeFormat;
        
        /* check if the current sample rate is the same as the requested one */
        if (__irefSampleRate != param->sRate)
        {
            rval = iref_AO_SetSRate(param->sRate);
            if (rval)
            {
                return rval;
            }
        }
        
        __irefAoInitialized = True;
    
        break;
    default:
        rval = AIO_ERR_UNSUPPORTED_FORMAT;
        break;
    }

    return rval;
}


/*******************************************************/
static tmLibdevErr_t iref_AO_term(void)
{
    tmLibdevErr_t   rval;
    
    /* reset statics */

⌨️ 快捷键说明

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