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

📄 xp_osi_clk.c

📁 IBM source for pallas/vulcan/vesta
💻 C
📖 第 1 页 / 共 3 页
字号:
/*----------------------------------------------------------------------------+|     This source code has been made available to you by IBM on an AS-IS|     basis.  Anyone receiving this source is licensed under IBM|     copyrights to use it in any way he or she deems fit, including|     copying it, modifying it, compiling it, and redistributing it either|     with or without modifications.  No license under IBM patents or|     patent applications is to be implied by the copyright license.||     Any user of this software should understand that IBM cannot provide|     technical support for this software and will not be responsible for|     any consequences resulting from the use of this software.||     Any person who transfers this source code or any derivative work|     must include the IBM copyright notice, this paragraph, and the|     preceding two paragraphs in the transferred software.||     COPYRIGHT   I B M   CORPORATION 1999|     LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+|| DESCRIPTION :  The set of functions allow the application to process|                the clock recovery interrupts.|+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+| Author    :  Andy Anderson, Ian Govett| Component :  xp| File      :  xp_clk.c| Purpose   :  Clock Recovery.| Changes   :|| Date:      By   Comment:| ---------  ---  --------| 15-Jan-98  IG   Created| 30-Sep-01  LGH  Ported to Linux| 01-aug-02  LGH  FIx the bug in PCR interrupt+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+|                              Clock Recovery+-----------------------------------------------------------------------------+||   The clock recovery is implemented by making use of both the hardware|   (auto-PWM), and software.  The software algorithm provides fast and|   accurate control necessary to quickly match the clock rates.  The|   hardware algorithm (auto-PWM) makes much smaller adjustments to|   "maintain" the proper clock rate.  The software algorithm is activated|   when the PCR PID is updated or when the STC & PCR differ by a|   programmable value.|   Once this difference is below a pre-determined threshold, the software|   algorithm shuts off.  At this time, the hardware algorithm (auto-PWM)|   continues to adjust the clock rate based on the current STC and|   arriving PCRs.  When the threshold is exceeded, the software algorithm|   is activated via a PCR type interrupt.  Using this technique, the|   number of clock recovery interrupts is greatly reduced.||   The clock recovery algorithm make use of two types of hardware|   interrupts:  STC_LOAD, and PCR.  An interrupt handler is registered|   when the clock recovery algorithm is started.  The hardware makes use|   of the PWM register to control the clock rate, and a threshold register|   to control when interrupts should be generated for the software|   algorithm.||   The following functions provide access to clock recovery algorithms|   available for the transport demux driver.  The clock recovery|   algorithms are enabled and disabled using the xp0_clk_start() and|   xp0_clk_stop() functions.  The xp0_clk_set_pid() function designates the|   PID value of the transport packets containing the PCR's.  The|   xp0_clk_get_stc_high() function provides the caller with the current|   value of the STC register which may be used by the decoder device|   driver for the decoders.|+----------------------------------------------------------------------------*//* The necessary header files */#include <linux/config.h>#include <linux/version.h>#ifdef MODVERSIONS#include <linux/modversions.h>#endif#define  __NO_VERSION__#include <linux/module.h>#include <linux/kernel.h>#include <linux/types.h>#include "xp_osi_global.h"#include "xp_atom_reg.h"XP_STC_NOTIFY_FN stc_notify_fn = NULL;/*----------------------------------------------------------------------------+| Local Defines+----------------------------------------------------------------------------*/#define PWM_CLAMP               50       /* Sets the maximum rate of change  */                                         /* of the PWM value                 */#define STC_LOAD_PWM_CLAMP      100      /* Sets the maximum rate of change  */                                         /* just after the PWM value is read */#define PCRS_HIGH_GAIN          10       /* Number of PCRs after the STC is  */                                         /* loaded which will use            */                                         /* STC_LOAD_PWM_CLAMP               */#define RATE_GAIN               4        /* The calculated rate difference   */                                         /* is divided by RATE_GAIN ^ 2      */#define DELTA_GAIN              4        /* The calculated delta             */                                         /* is divided by DELTA_GAIN ^ 2     */#define LOW_THRESHOLD           32       /* Lower Delta Threshold for the    */                                         /* s/w clock recovery algorithm     */#define HIGH_THRESHOLD          256      /* Upper Delta Threshold for the    */                                         /* s/w clock recovery algorithm     */#define DECODE_DELAY ((unsigned long) 10)/* decode delay                     *///Internalstatic void pcr_interrupt(GLOBAL_RESOURCES *pGlobal,ULONG ulInterrupt);/*----------------------------------------------------------------------------+| XXXX   XX   XX   XXXXXX  XXXXXXX  XXXXXX   XX   XX     XX    XXXX|  XX    XXX  XX   X XX X   XX   X   XX  XX  XXX  XX    XXXX    XX|  XX    XXXX XX     XX     XX X     XX  XX  XXXX XX   XX  XX   XX|  XX    XX XXXX     XX     XXXX     XXXXX   XX XXXX   XX  XX   XX|  XX    XX  XXX     XX     XX X     XX XX   XX  XXX   XXXXXX   XX|  XX    XX   XX     XX     XX   X   XX  XX  XX   XX   XX  XX   XX  XX| XXXX   XX   XX    XXXX   XXXXXXX  XXX  XX  XX   XX   XX  XX  XXXXXXX+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+|  pcr_interrupt+-----------------------------------------------------------------------------+||  FUNCTION    :  pcr_interrupt||  DESCRIPTION :  This function is called by an interrupt service|                 routine whenever an PCR or STC is processed by hardware||  COMMENTS    :  This function is processed in the interrupt context|                 and must be careful to only use functions which are|                 safe within the context of an interrupt.  Do NOT use|                 any I/O instructions such as printf() or gets(), etc.||                 Portions of this function could be shared with the|                 other interrupt routine.  The question is how to best|                 optimize the interrupt routines and the overhead|                 of function calls.||                 The other option which is better is to integrate both|                 functions and setup so that the single function is|                 called in either case|+----------------------------------------------------------------------------*/static void pcr_interrupt(GLOBAL_RESOURCES *pGlobal,ULONG ulInterrupt){    unsigned        overflow;         /* Delta Overflow bit                  */    unsigned long   delta;            /* Delta or Delta Magnitude            */    unsigned long   tdelta;    short           rate_adjust;      /* Adjustment to PWM based on frequency*/    short           pwm_adjust;       /* The amount to adjust the pwm        */    unsigned long   pwm;              /* Current PWM value                   */    unsigned long   new_pwm;          /* Updated PWM value                   */    short           soft_overflow;    /* software algorithm overflow         */    long            delta_pcr;        /* Difference between the current      */    long            delta_stc;        /* and previous values                 */    long            temp1;    long            temp2;    long            value_adjust;     /* Adjustment to PWM based on delta    */    unsigned long   stc_high;    unsigned long   stc_low;    unsigned long   pcr_high;    unsigned long   pcr_low;    unsigned long   stc;    unsigned long   pcr;    XP_PCRSTCD_REGP p_delta;    UINT32          flag;    /*------------------------------------------------------------------------+   |  Read the STC, PCR, and delta values    +------------------------------------------------------------------------*/    flag = os_enter_critical_section();    pcr_high = xp_atom_dcr_read(pGlobal->uDeviceIndex,XP_DCR_ADDR_PCRHI);    pcr_low  = xp_atom_dcr_read(pGlobal->uDeviceIndex,XP_DCR_ADDR_PCRLOW);    stc_high = xp_atom_dcr_read(pGlobal->uDeviceIndex,XP_DCR_ADDR_LSTCHI);    stc_low  = xp_atom_dcr_read(pGlobal->uDeviceIndex,XP_DCR_ADDR_LSTCLOW);    tdelta   = xp_atom_dcr_read(pGlobal->uDeviceIndex,XP_DCR_ADDR_PCRSTCD);    os_leave_critical_section(flag);    p_delta  = (XP_PCRSTCD_REGP)(void *) &tdelta;    delta    = p_delta->delta;    overflow = p_delta->ovfl;    if(overflow)    {        delta = ~0;    }    /*------------------------------------------------------------------------+    |   Make sure the clock recovery registers are consistent    |   Later the value of Incons_data can be returned as    |   part of the status of the driver.    |   This is a candidate to be removed later.    +------------------------------------------------------------------------*/    flag = os_enter_critical_section();    if(pcr_low != xp_atom_dcr_read(pGlobal->uDeviceIndex,XP_DCR_ADDR_PCRLOW))    {        pGlobal->ClkInfo.XpClkInconsData++;        return;    }    os_leave_critical_section(flag);    /*------------------------------------------------------------------------+    |  Track number of PCRS Since STC loaded    +------------------------------------------------------------------------*/    if(ulInterrupt & XP_INTERRUPT_IR_STCL)    {        pGlobal->ClkInfo.XpClkNpcrs = 0;                        /* Initialize to 0         */        if(stc_notify_fn != NULL)            (*stc_notify_fn)(pGlobal,STC_DISCONTINUITY);

⌨️ 快捷键说明

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