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

📄 int_proc.h

📁 本程序为ST公司开发的源代码
💻 H
📖 第 1 页 / 共 5 页
字号:
/************************************************************************
*               C-EMERALD code for ACCORDO  ( 15 - 05 - 2003 )
*               Ver:  ver0.2
*
*               File: int_proc.c (interrupt procedures)
*
*               Author: A. Di Carlo
************************************************************************/

/*******************************************************************************
 * - MR041215     Optimized TTM controller
 *                  - Increased controller bandwidth, CLV 1X 17Hz/35Hz
 *                    (inside/outside).
 *                  - Added hold functionality, ST7 can force the TTM
 *                    controller to hold its state and output.
 *                  - During a defect (DEFOK) and during a short jump the state
 *                    of the controller is held (implemented in the DSP).
 * - MR20050106   Problem: Turntable motor often came to a halt or rotated
 *                backwards after a jump from track 1 to the last track or vice
 *                versa. The fixes are described in the following points: a, b
 *                and c.
 * - MR20050106a  Changed the thresholds that determine whether or not the
 *                correct TTM velocity has been reached in CLV mode. Especially
 *                the value for the phase was too high.
 * - MR20050106b  Introduced a timer which makes sure that the TTM velocity is
 *                within the defined range for at certain period of time before
 *                the DSP notifies the ST7 that the correct speed has been
 *                reached.
 * - MR20050106c  When the TTM controller switches to hold mode (either by the
 *                ST7, during a short jump or a defect) it will not be allowed
 *                to brake the TTM. If the TTM controller output is negative
 *                during the hold mode then its output is set to zero.
 * - MR20050523a  Fixed FG-period error calculation in TTM controller.
 * - MR20050523b  Added high frequency FG pulse detection. High frequency FG
 *                pulses are assummed to be caused by a stopped TTM. In order
 *                to recover from this situation, the I-action is loaded with
 *                a value that results in the maximum allowed value at the
 *                controller output to restart the TTM and the ST7 is notified
 *                about this situation. Normally the TTM restarts without pro-
 *                blems when the focus and radial loops are open. Opening these
 *                loops should be done in the ST7.
 * - MR20050523c  Changed limit on TTM controller output from one +/- level to
 *                a maximum and a minimum level.
 * - MR20051115c  Generate the speed_ok signal on the CLV buffer level only
 * - MR20051115d  Modified the handling of sledge controller. such that sledge not moved
 *                during defects
 * - MR20051115e  In tracking controller, shift gain is removed and compensated
 *                by changing the value of other coefficients
 * - MR20060201a  Interpolate fe during defect, also during short jumps.
 * - MR20060201b  Optimized noiseshaping (less instructions, i.e. faster).
 * - MR20060201c  Error fond in the previous optimized version of the deadzone.
 *                Implementation has been rewritten, works correcly now and
 *                uses one instruction less. Note the difference in the use of
 *                nlc_delta.
 * - MR20060201d  Optimized the "shift-out prevention" in the TTM controller.
 * - FD060929a    Fixed detection of very short focus ramping
 *******************************************************************************/

#ifndef QAC_CHECK
  #define MACRO   # ## macro
#else
  #define MACRO   void
#endif


MACRO interrupt_decimation2_handle()
{
#if (1 == SAMPLERATE_TESTING)
  /* Cycle start put gpio to 1 for monitoring */
  GPIO_RW = 0x0f;
  if (count16 == 0) {
    GPIO_RW = 0x00;   /* Mark count16 == 0 using a double pulse */
    GPIO_RW = 0x0f;
  }
#endif

#if (1 == DSP_PROC_ENABLE)
  if (proc_enable) {
#endif
      err_gen();                                /* Generate error signals + defect detection */
      focus();                                  /* Execute focus controller */
      if (int_mode == TRK_MODE) goto CASE_TRK;  /* Assume adjust-mode when tracking controller is switched off */
      adjust();                                 /* Execute adjustment procedures before focus and tracking controller can be switched on */
/*      goto END_SWITCH;*/
    CASE_TRK:
      track();                                  /* Execute radial tracking controller, including the nonlinear control */
    END_SWITCH:
#if (1 == DEBUG_DSP || 2 == DEBUG_DSP)
      test_out();                               /* Output signals through the test_pdm DACs, for debuging only */
#endif
      misc();                                   /* Other things suchs as TTM controller, AGC and generation hfok, teok and fok. */
#if (1 == DSP_PROC_ENABLE)
  }
#endif

  dsp_arm_communication();                      /* Reports ARM the new DSP state when this has changed and calls read/write x/y memory routine. */

#if (1 == SAMPLERATE_TESTING)
  /* cycle end put gpio to 0 for monitoring*/
  GPIO_RW = 0x00;
#endif
}
#endm


MACRO err_gen()
{
  fraction * delay;         /* TO DO: LOCAL VARIABLE NOT ALLOWED IN INTERRUPT ROUTINE */
  memoryY CONST * c;        /* TO DO: LOCAL VARIABLE NOT ALLOWED IN INTERRUPT ROUTINE */
  register fraction accu0 at(acc[0]);
  register fraction accu1 at(acc[1]);
  register fraction dx0 at(dx[0]);
  register fraction dx1 at(dx[1]);
  register fraction dy0 at(dy[0]);
  register fraction dy1 at(dy[1]);

  c = coeff_error;
  delay = delay_error;

  /* The radial tracking error (te) is generated by the RATE block. */
#if (1 == WORKAROUND_SPIKE_BUG)
  /* When the DSP processing time takes longer than the sampling period, set by the     */
  /* decimation filters, the decimation registers are not read immediately after a      */
  /* decimation interrupt but some undefined period of time after this. If there are    */
  /* multiple processing cycles in a row that take longer than the sampling period      */
  /* then the time between the decimation interrupt and the reading of the decimation   */
  /* registers increases until a sample is lost. A sample is lost when two consecutive  */
  /* interrupts occur in one processing cycle, in that case the sample corresponding    */
  /* to the first interrupt is lost. Another problem that may occur in this case when   */
  /* the decimation registers are not immediately read after an interrupt is that the   */
  /* register is read by the DSP the moment an new value is written in to the registers */
  /* by the decimation filters. If this is the case then the values read by the DSP are */
  /* are corrupted. A work-around for the last problem is reading the decimation        */
  /* register twice and comparing both read values, if they are the same then the value */
  /* is a valid if not then a third read of the decimation register will give a valid   */
  /* value.                                                                             */

  dx0 = E_IN;
  dy0 = E_IN;
  if (dx0 != dy0) {    /* Check if read value is valid. */
    dx0 = E_IN;        /* If not: the third read will produce a valid value, see above. */
  }
#else
  dx0 = E_IN;
#endif

  accu1 = dx0 * c[3];
  te = (accu1 << 1);

#if (0 != DEBUG_DSP)
  e_in = dx0;

#if (1 == WORKAROUND_SPIKE_BUG)
  dx0 = F_IN;
  dy0 = F_IN;
  if (dx0 != dy0) {    /* Check if read value is valid. */
    dx0 = F_IN;       /* If not: the third read will produce a valid value, see above. */
  }
#else
  dx0 = F_IN;
#endif

  f_in = dx0;
#endif

  /* Read AC detector signal. */
#if (1 == WORKAROUND_SPIKE_BUG)
  dx0 = AC_IN;
  dy0 = AC_IN;
  if (dx0 != dy0) {    /* Check if read value is valid. */
    dx0 = AC_IN;       /* If not: the third read will produce a valid value, see above. */
  }
  accu0 = dx0;
#else
  dx0 = AC_IN;
  accu0 = dx0;
#endif

#if (0 != DEBUG_DSP)
  ac_in = dx0;
#endif

  /* Read BD detector signal. */
#if (1 == WORKAROUND_SPIKE_BUG)
  dx1 = BD_IN;
  dy1 = BD_IN;
  if (dx1 != dy1) {    /* Check if read value is valid. */
    dx1 = BD_IN;       /* If not: the third read will produce a valid value, see above. */
  }
#else
  dx1 = BD_IN;
#endif

#if (0 != DEBUG_DSP)
  bd_in = dx1;
#endif

  /* Calculation of the focus tracking error (fe) from AC and BD. */
  accu1 = dx0 * c[0] - dx1 * c[1] - c[2];
  fe = (accu1 << 1);

  /* Generation of the low frequent center aperture signal (hfl) from AC and BD. */
  accu0 += dx1;

#if (0 != DEBUG_DSP)
  hf_deb = accu0 >> 1;
#endif

  /* Scale and translate the hfl signal such that it is always positive. */
  accu0 -= c[4];
  accu0 -= c[4];
  accu0 = accu0 >> 2;

  hfl = accu0;

  /* Fast filter, operating on the scaled and translated hfl signal. */
  accu1 = accu0 * c[5] + c[6] * delay[0];
  delay[0] = accu1;

  /* Slow filter, filtering the output of the fast filter. */
  accu0 = delay[0] * c[7] + c[8] * delay[1];
  delay[1] = accu0;

  /* Detect black dot if slow filter is larger than fast filter by */
  /* a certain amount. Results in 0x0001 if detect detected, otherwise 0x0000. */
  accu1 = ((int)((c[9] * delay[1] - accu1) >> 15) + 0x0001);
  bd_defect = (int)accu1 | DEFFOK;

  accu0 = ((int)((c[10] * delay[0] - hfdc) >> 15) + 0x0001);
  wd_defect = (int)accu0;

  accu1 = (bd_defect << 1) - 1;     /* 1 if bd_defect active otherwise -1. */
  accu1 = ((int)accu1 + bd_cnt);    /* Increase/decreas counter. */
  accu0 = ((int)accu1 >> 15);       /* Make counter zero when it */
  accu1 = (int)accu1 & (int)accu0;  /* becomes negative. */
  bd_cnt = (int)accu1;

  /* Increase white dot counter during defect, decrease outside defect. */
  accu1 = (wd_defect << 1) - 1;     /* 1 if wd_defect active otherwise -1. */
  accu1 = ((int)accu1 + wd_cnt);    /* Increase/decreas counter. */
  accu0 = ((int)accu1 >> 15);
  accu1 = (int)accu1 & (int)accu0;
  wd_cnt = (int)accu1;

  if (((int)accu1 - wd_cnt_max) >> 15)
  {
    bd_cnt = accu1;
  }


  /* Mask the generation of a black dot defect */
  /* during and shortly after a white dot. */
  /* Result: defect detected -> 0x0001 otherwise -> 0x0000. */
  bd_defect_m = (bd_defect & ((-wd_cnt) >> 15)) | DEFFOK;

  /* Mask the generation of a white dot defect */
  /* during and shortly after a black dot. */
  /* Result: defect detected -> 0x0001 otherwise -> 0x0000. */
  wd_defect_m = wd_defect & ((-bd_cnt) >> 15);

  /* Generate defect signal for focus loop. */
  /* Result: defect detected -> 0x0001 otherwise -> 0x0000. */
  fcs_defect = bd_defect_m & def_ena;

  /* Generate defect signal for focus loop. */
  /* Result: defect detected -> 0x0001 otherwise -> 0x0000. */
/*  trk_defect = (wd_defect_m | bd_defect_m) & def_ena; */
  trk_defect = bd_defect_m & def_ena;
}
#endm


MACRO init_focus()
{
#if (1 == OPTIMIZED_INIT)
  /* Nothing to be done, everything is already reset to zero. */
#else
  fraction * k;
  integer i;

  k = delay_focus;
  fcs_off = 0;
  fosc = 0;
  fcrint = 0;
  for (i = 0; i < MAX_DIM_DELAY_FOCUS; i++)
  {
    k[i] = 0;
  }
#endif
}
#endm

/************************************************************************/

MACRO focus()
{
  fraction * delay;
  memoryY CONST * c;
  register fraction pacc at(p);
  register fraction accu0 at(acc[0]);
  register fraction accu1 at(acc[1]);
  register int int_accu1 at(acc[1]);
  register fraction dx0 at(dx[0]);
  register fraction dy0 at(dy[0]);

  c = coeff_focus;
  delay = delay_focus;


  /* PID controller for the focus loop. */
  accu0 = FCR_ON_INT & fcrint & fok;
  fcrint = accu0;
  if (accu0 != 0)     /* Focus loop closed. */
  {
    dsp_state = get_set_focus_closed(dsp_state);

    /* Slope filter that generates the interpolated fe-signal value */
    /* during a defect. */
    dx0 = delay[0];
    accu1 = fe;
#if FE_INTERP_DURING_JUMPS_AND_DEFECTS
    if (fcs_defect)  /* Interpolate fe during a defect, also during short jumps MR060201a. */
#else
    if (fcs_defect & (~jump_mode))  /* Interpolate fe during a defect. */
#endif
    {
      accu1 = dx0;
    }
    else                            /* Update slope filter when no is defect present. */
    {
      dy0 = c[0];
      if (accu1 > dx0)
      {
        accu0 = dx0 + dy0;
      }
      else
      {
        accu0 = dx0 - dy0;
      }
      delay[0] = accu0;
    }
    fe = accu1;



    /*-------------- I part of PID (with decimation) */
    delay[1] += (accu1 >> 4);      /* Decimation using an accumulate-and-drop filter. */
    if (count16 == 5)
    {
      accu0 = delay[1] * c[1] + delay[2] * c[2];
      if (!fcs_defect)                    /* Hold integrator during a defect. */
      {
        delay[2] = accu0;
      }
      delay[1] = 0;                       /* The "drop" part of the accumulate-and-drop filter. */
    }

    /*-------------- PD part of PID ----------------*/
    accu1 = accu1 * c[3];
    accu0 = accu1 + c[4] * delay[3] + c[5] * delay[4];
    delay[3] = accu1;
    delay[4] = accu0;
    accu0 = accu0 + c[6] * delay[5];
    dy0 = c[7];
    delay[5] = accu0;
    accu1 = accu0 << (int)dy0;     /* Result of PD part in accu1. */

    /*-------------- Combine I and PD parts, result is accu0 ----------------*/

⌨️ 快捷键说明

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