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

📄 xp_osi_clk.c

📁 IBM source for pallas/vulcan/vesta
💻 C
📖 第 1 页 / 共 3 页
字号:
    }    if(pGlobal->ClkInfo.XpClkNpcrs <= PCRS_HIGH_GAIN)    {         /* Still in the high gain  */        pGlobal->ClkInfo.XpClkNpcrs++;    }    /*------------------------------------------------------------------------+    |   Normalize the STC and PCR    |   This drops the upper 10 bits of both the PCR and the STC    |   This also detects if either the PCR or STC has wrapped    |   and other has not.  In either case the software algorithm    |   doesn't run.    +------------------------------------------------------------------------*/    stc = (((stc_high & 0x003FFFFF) * 2) + ((stc_low & 0x200) >> 9)) * 300;    stc = stc + (stc_low & 0x1FF);    pcr = (((pcr_high & 0x003FFFFF) * 2) + ((pcr_low & 0x200) >> 9)) * 300;    pcr = pcr + (pcr_low & 0x1FF);    /*------------------------------------------------------------------------+    |  Check if the upper 10 bits are the same.    |  The software clock recovery algorithm is not used if    |  soft_overflow occurs.    |  Also check if hardware overflow has occured and treat    |  like a software overflow - pag 7/16/99    +------------------------------------------------------------------------*/    if(overflow || (stc_high & 0xFFC00000) != (pcr_high & 0xFFC00000))    {        stc = stc_high & 0xFFC00000;        pcr = pcr_high & 0xFFC00000;        soft_overflow = 1;        pGlobal->ClkInfo.XpClkErrs++;                  /* Increment the global error count */        /*--------------------------------------------------------------------+        |  if there were two consecutive errors, force a PCR reload        +--------------------------------------------------------------------*/        if(pGlobal->ClkInfo.wXpClkPrevErr == 1)        {            flag = os_enter_critical_section();            xp_osi_clk_set_pid(pGlobal,xp_atom_dcr_read(pGlobal->uDeviceIndex,XP_DCR_ADDR_PCRPID));            os_leave_critical_section(flag);            pGlobal->ClkInfo.wXpClkPrevErr = 0;        }        else        {            pGlobal->ClkInfo.wXpClkPrevErr = 1;        }    }    else    {        soft_overflow   = 0;        pGlobal->ClkInfo.wXpClkPrevErr = 0;    }    /*------------------------------------------------------------------------+    |   Run the software algorithm if there are no errors    |   Adjust auto PWM if the delta is large    +------------------------------------------------------------------------*/    if(soft_overflow == 0)    {        delta_pcr = pcr - pGlobal->ClkInfo.XpClkPrevPcr;        delta_stc = stc - pGlobal->ClkInfo.XpClkPrevStc;        temp1 = delta_pcr - delta_stc;        temp2 = 27000000 / delta_pcr;        rate_adjust = (temp1 * temp2) >> RATE_GAIN;//lingh changed it        value_adjust = (pcr - stc) >> DELTA_GAIN;        pwm_adjust = rate_adjust + value_adjust;        /*--------------------------------------------------------------------+        |  Once the delta is small enough increase the threshold        |  and use only autopwm until this function is called        |  again, then increase the threshold.        +--------------------------------------------------------------------*/        if((delta < LOW_THRESHOLD) && (pGlobal->ClkInfo.lXpClkPrevDelta < LOW_THRESHOLD))        {            pGlobal->ClkInfo.uwXpClkThreshold = HIGH_THRESHOLD;            flag = os_enter_critical_section();            xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_PCRSTCT, pGlobal->ClkInfo.uwXpClkThreshold);            os_leave_critical_section(flag);        }        else if(pGlobal->ClkInfo.uwXpClkThreshold != 0)        {            pGlobal->ClkInfo.uwXpClkThreshold = 0;            flag = os_enter_critical_section();            xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_PCRSTCT, pGlobal->ClkInfo.uwXpClkThreshold);            os_leave_critical_section(flag);        }        pGlobal->ClkInfo.XpClkPrevStc   = stc;        pGlobal->ClkInfo.XpClkPrevPcr   = pcr;        pGlobal->ClkInfo.lXpClkPrevDelta = delta;        /*--------------------------------------------------------------------+        |  Restrict the rate of change of the PWM value.        |  For the first few PCRs received after the STC is        |  loaded the clamp value is larger so that the local        |  clock moves closer to the multiplexor clock quickly.        |  After that reduce use a smaller clamp value.        +--------------------------------------------------------------------*/        if (pGlobal->ClkInfo.XpClkNpcrs <= PCRS_HIGH_GAIN)        {           /* clamp adjustment */            if(pwm_adjust > STC_LOAD_PWM_CLAMP)            {                pwm_adjust = STC_LOAD_PWM_CLAMP;            }            else if(pwm_adjust < -STC_LOAD_PWM_CLAMP)            {                pwm_adjust = -STC_LOAD_PWM_CLAMP;            }        }        else        {            if(pwm_adjust > PWM_CLAMP)            {                pwm_adjust = PWM_CLAMP;            }            else if(pwm_adjust < -PWM_CLAMP)            {                pwm_adjust = -PWM_CLAMP;            }        }        flag = os_enter_critical_section();        pwm     = xp_atom_dcr_read(pGlobal->uDeviceIndex,XP_DCR_ADDR_PWM);        os_leave_critical_section(flag);        new_pwm = pwm + pwm_adjust;        /*--------------------------------------------------------------------+        |  PWM range is actually a signed 12 bit number        |  whose range is 0x800 - 0x7ff.  So after calculating        |  the new pwm, make sure we don't exceed the above bounds        +--------------------------------------------------------------------*/        if((pwm <= 0x07ff) && (new_pwm > 0x07ff) && (pwm_adjust > 0))        {            new_pwm = 0x07ff;        }        else if((pwm >= 0x0800) && (new_pwm < 0x0800) && (pwm_adjust < 0))        {            new_pwm = 0x0800;        }        flag = os_enter_critical_section();        xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_PWM, new_pwm); /* Update the PWM register  */        os_leave_critical_section(flag);    }}/*----------------------------------------------------------------------------+| XXXXXXX  XXX XXX   XXXXXX  XXXXXXX  XXXXXX   XX   XX     XX    XXXX|  XX   X   XX XX    X XX X   XX   X   XX  XX  XXX  XX    XXXX    XX|  XX X      XXX       XX     XX X     XX  XX  XXXX XX   XX  XX   XX|  XXXX       X        XX     XXXX     XXXXX   XX XXXX   XX  XX   XX|  XX X      XXX       XX     XX X     XX XX   XX  XXX   XXXXXX   XX|  XX   X   XX XX      XX     XX   X   XX  XX  XX   XX   XX  XX   XX  XX| XXXXXXX  XXX XXX    XXXX   XXXXXXX  XXX  XX  XX   XX   XX  XX  XXXXXXX+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+|  xp0_clk_get_stc_high+-----------------------------------------------------------------------------+||  DESCRIPTION:  allocates a channel for the requested type||  PROTOTYPE  :  short xp0_clk_get_stc_high(|                unsigned long *p_stc_high)||  ARGUMENTS  :  p_stc_high    -  the upper 32 bits of the stc, returned||  RETURNS    :  zero if the stc is valid, or non-zero if invalid||  ERRORS     :  XP_ERROR_INVALID_STC||  COMMENTS   :  The stc value is determined if it is valid if a recent|                PCR value was loaded.  Note: During a channel change,|                there is an interval between the time the new PCR pid is|                written, and the arrival of the first PCR where the STC,|                could be considered either valid or invalid.  This|                function assumes the STC is valid for this duration.|+----------------------------------------------------------------------------*/SHORT xp_osi_clk_get_stc_high(GLOBAL_RESOURCES *pGlobal,ULONG *pStcHigh){    short rc;    short i;    unsigned long stc_high=0;    unsigned long lstc_high=0;    unsigned long lstc_high2=0;    unsigned long diff;    UINT32  flag;    /*------------------------------------------------------------------------+    |  Do not use xp0_os_semaphore_wait() since called from an interrupt    +------------------------------------------------------------------------*/    /*------------------------------------------------------------------------+    |  Get STC and Latched STC values.  Since the hardware could    |  receive a PCR at any time, we re-read the STC Latched Register    |  twice to make sure the value is still the same.    +------------------------------------------------------------------------*/    flag = os_enter_critical_section();    for(i=0; i<2; i++)    {        lstc_high  = xp_atom_dcr_read(pGlobal->uDeviceIndex,XP_DCR_ADDR_LSTCHI);        stc_high   = xp_atom_dcr_read(pGlobal->uDeviceIndex,XP_DCR_ADDR_STCHI);        lstc_high2 = xp_atom_dcr_read(pGlobal->uDeviceIndex,XP_DCR_ADDR_LSTCHI);        if(lstc_high == lstc_high2) {            break;        }    }    os_leave_critical_section(flag);    /*------------------------------------------------------------------------+    |  Compare the Two Latched STC Values Read, A PCR must have been    |  Received if their Different    +------------------------------------------------------------------------*/    rc = (lstc_high != lstc_high2) ? XP_ERROR_INVALID_STC : 0;    /*------------------------------------------------------------------------+    |   The STC is considered valid if a recent PCR has been received.    |   Each PCR received is loaded into the STC Latched register.  So, we    |   compare the values of the STC Latched and the STC registers whose    |   difference should be within the expected arrival rate of PCR's.    |    |   The calculation is as follows:    |       STC clock is 27 MHZ, PCR arrival rate=100ms    |       The upper 32 bits of the STC are modulo 600    |    |       difference    =  2.7E6 / 600    |                     =  4500    |    |   Add a 1% margin so we don't hit the edge condition exactly    |   and are somewhat tolerant of non-compliant streams.    |    |      4500 x  1.01  = 4545    |    |   STC is valid if | STC - STCHOLD | < 4545    |    |   Note: We have to account for the STC wrapping.    +------------------------------------------------------------------------*/    /*------------------------------------------------------------------------+    |  Since these are both unsigned, there is not a Wrapping Issue    +------------------------------------------------------------------------*/    if (rc == 0)    {       diff = stc_high - lstc_high;       if (diff > 4545)       {          rc = XP_ERROR_INVALID_STC;       }    }    if (rc == 0 && pGlobal->ClkInfo.XpClkNpcrs == 0)    {       rc = XP_ERROR_INVALID_STC;    }    *pStcHigh = stc_high;    return(rc);}/*----------------------------------------------------------------------------+|  xp0_clk_init+----------------------------------------------------------------------------*/SHORT xp_osi_clk_init(GLOBAL_RESOURCES *pGlobal){    pGlobal->ClkInfo.XpClkInstalled = 0;    return(0);}/*----------------------------------------------------------------------------+|   XX     XXXXXX    XXXXXX    XXXXX

⌨️ 快捷键说明

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