📄 int_proc.h
字号:
accu0 = dx1 >> dy0_int; /* sig[i+1] >> 2 */
/***** i = 6 *****/
dx0 = *ax0; /* sigdec_var[i] */
accu0 = accu0 + dx0; /* sigdec_var[i] + sig[i] >> 2 */
/* dx1 = *ay0++; */ /* sig[i+1] */
*ax0++ = accu0; /* sigdec_var[i] += sig[i] >> 2 */
/* accu0 = dx1 >> dy0_int; */ /* sig[i+1] >> 2 */
#else
fedec_var += (fe >> 2);
tedec_var += (te >> 2);
fadec_var += (fa >> 2);
fa2dec_var += (fa2 >> 2);
tadec_var += (ta >> 2);
ta2dec_var += (ta2 >> 2);
hfldec_var += (hfl >> 2);
#endif
goto END_SWITCH3;
CASE_11:
if (gainadj & 0x01)
{
if (gainadj & 0x02)
{
/* Select tracking loop for AGC amplitude measurement, */
/* result -> amp2. */
accu0 = tadec * c[0];
}
else
{
/* Select focus loop for AGC amplitude measurement, */
/* result -> amp2. */
accu0 = fadec * c[0];
}
/* Amplitude amp2 is determined in three steps: */
/* 1. Filter signal using a notch filter with centre */
/* frequency at controller bandwidth. */
accu1 = accu0 - delay[3] + delay[4] * c[1];
delay[3] = accu0;
pacc = c[2] * delay[5];
accu0 = accu1 + pacc;
accu0 += pacc;
delay[4] = delay[5];
delay[5] = accu0;
/* 2. Take absolute value of filtered signal. */
accu1 = abs(accu0);
/* 3. Lowpass filter the absolute value. */
accu0 = accu1 * c[3] + amp2 * c[4];
/* Result: amp2 */
amp2 = accu0;
}
else
{
/* Set default values for variable used in the AGC procedure */
/* when it turned off. */
stima = 0x2000;
amp1 = 0x4000;
amp2 = 0x4000;
agc_minmax_extreme = 0x2000;
agc_minmax_state = 0x7fff; /* Start searching for maximum. */
agc_minmax_cnt = 0;
}
/* downsampling of internal signals */
#if ((1 == OPTIMIZED_DEC) && (1 == HARDWARE_LOOP))
ax0 = SIGDEC_VAR_ARRAY_ADD;
ay0 = SIGDEC_ARRAY_ADD; /* ay0+7 equals SIG_ARRAY_ADD */
dy1 = ay0[7]; /* sig[0] */
loop(7)
{
dy0 = *ax0; /* sigdec_var[i] */
accu0 = dy1; /* sig[i] */
accu0 = accu0 >> 2; /* sig[i] >> 2 */
*ay0++ = dy0; /* sigdec[i] = sigdec_var[i] */
*ax0++ = accu0; /* sigdec_var[i] = sig[i] >> 2 */
dy1 = ay0[7]; /* sig[i+1] */
}
#elif (1 == OPTIMIZED_DEC) /* DOES NOT SEEM TO WORK */
ax0 = SIGDEC_VAR_ARRAY_ADD;
ay0 = SIGDEC_ARRAY_ADD; /* ay0+7 equals SIG_ARRAY_ADD */
dy1 = ay0[7]; /* sig[0] */
/***** i = 0 *****/
dy0 = dy1;
dy0 = *ax0; /* sigdec_var[i] */ /* dy0 makes problems, dy1 not. Why ? */
accu0 = dy1; /* sig[i] */
accu0 = accu0 >> 2; /* sig[i] >> 2 */
*ay0++ = dy0; /* sigdec[i] = sigdec_var[i] */
*ax0++ = accu0; /* sigdec_var[i] = sig[i] >> 2 */
dy1 = ay0[7]; /* sig[i+1] */
/***** i = 1 *****/
dy0 = *ax0; /* sigdec_var[i] */
accu0 = dy1; /* sig[i] */
accu0 = accu0 >> 2; /* sig[i] >> 2 */
*ay0++ = dy0; /* sigdec[i] = sigdec_var[i] */
*ax0++ = accu0; /* sigdec_var[i] = sig[i] >> 2 */
dy1 = ay0[7]; /* sig[i+1] */
/***** i = 2 *****/
dy0 = *ax0; /* sigdec_var[i] */
accu0 = dy1; /* sig[i] */
accu0 = accu0 >> 2; /* sig[i] >> 2 */
*ay0++ = dy0; /* sigdec[i] = sigdec_var[i] */
*ax0++ = accu0; /* sigdec_var[i] = sig[i] >> 2 */
dy1 = ay0[7]; /* sig[i+1] */
/***** i = 3 *****/
dy0 = *ax0; /* sigdec_var[i] */
accu0 = dy1; /* sig[i] */
accu0 = accu0 >> 2; /* sig[i] >> 2 */
*ay0++ = dy0; /* sigdec[i] = sigdec_var[i] */
*ax0++ = accu0; /* sigdec_var[i] = sig[i] >> 2 */
dy1 = ay0[7]; /* sig[i+1] */
/***** i = 4 *****/
dy0 = *ax0; /* sigdec_var[i] */
accu0 = dy1; /* sig[i] */
accu0 = accu0 >> 2; /* sig[i] >> 2 */
*ay0++ = dy0; /* sigdec[i] = sigdec_var[i] */
*ax0++ = accu0; /* sigdec_var[i] = sig[i] >> 2 */
dy1 = ay0[7]; /* sig[i+1] */
/***** i = 5 *****/
dy0 = *ax0; /* sigdec_var[i] */
accu0 = dy1; /* sig[i] */
accu0 = accu0 >> 2; /* sig[i] >> 2 */
*ay0++ = dy0; /* sigdec[i] = sigdec_var[i] */
*ax0++ = accu0; /* sigdec_var[i] = sig[i] >> 2 */
dy1 = ay0[7]; /* sig[i+1] */
/***** i = 6 *****/
dy0 = *ax0; /* sigdec_var[i] */
accu0 = dy1; /* sig[i] */
accu0 = accu0 >> 2; /* sig[i] >> 2 */
*ay0++ = dy0; /* sigdec[i] = sigdec_var[i] */
*ax0++ = accu0; /* sigdec_var[i] = sig[i] >> 2 */
/* dy1 = ay0[7];*/ /* sig[i+1] */
#else
fedec = fedec_var;
fedec_var = (fe >> 2);
fadec = fadec_var;
fadec_var = (fa >> 2);
fa2dec = fa2dec_var;
fa2dec_var = (fa2 >> 2);
tedec = tedec_var;
tedec_var = (te >> 2);
tadec = tadec_var;
tadec_var = (ta >> 2);
ta2dec = ta2dec_var;
ta2dec_var = (ta2 >> 2);
hfldec = hfldec_var;
hfldec_var = (hfl >> 2);
#endif
accu1 = hfldec * c[10] + c[11] * hfdc;
hfdc = accu1;
goto END_SWITCH3;
CASE_22:
if (gainadj & 0x01)
{
/* The quotient amp2/amp1 specifies the gain adjustment that */
/* is necessary in order to set the bandwidth of the closed */
/* system to the speciefied value. */
/* An estimate of amp2/amp1 is determined here using a kind */
/* LMS method. The result in stima converges to the value */
/* amp1/amp2. (Actually the quotient amp2/(amp1*4) is calcu- */
/* lated, the factor 4 if later compensated for when adjus- */
/* the loop gain. The factor 4 assures that the resulting */
/* stima is in the range 0..1, even if amp2 is 4 times */
/* larger than amp1. */
accu0 = (amp2 >> 2) - (amp1 * stima);
accu1 = (accu0 * amp1) * c[5];
stima += accu1;
/* Due to the eccentricity of the disc and the variable */
/* laging of the of the slegde the tracking error signal */
/* will cause the tracking error to change as the disc */
/* rotates. This together with the fact that the tracking */
/* generation, using the pushpull method, introduces a non- */
/* linear effect caused the loop gain of the controller to */
/* change as the disc rotates. The largest loop gain occures */
/* as the tracking error is around zero. At this moment */
/* the quotient amp1/amp2 will at it minimum. In the focus */
/* direction the vertical deviation of the disc causes the */
/* same sort of effects. */
/* The following code determines for both the tracking and */
/* focus AGC procedure the minimum value of the the quotient */
/* amp1/amp2 of which the estimate is stored in the variable */
/* stima. When a minimum is found the loop gain of the */
/* corresponding controller corrected using this minumum. */
/* This procedure is repeated agc_minmax_nr_cycles times in */
/* order to get a more accurate gain correction. */
if (agc_minmax_nr_cycles > 0)
{
/* Correct the loop gain using agc_minmax_nr_cycles */
/* successive measurements followed by a gain adjustment */
/* in order to arrive at an accurate loop gain that */
/* corresponds to the desired close loop bandwidth. */
if (agc_minmax_state > 0)
{
/* Search for a maximum. */
if (stima > agc_minmax_extreme)
{
/* Current sample larger than any of the */
/* previously seen values since searching for a */
/* maximum. */
agc_minmax_cnt = 0;
agc_minmax_extreme = stima;
}
else
{
/* Current sample value smaller than the largest */
/* seen value up to now. */
++agc_minmax_cnt;
if (agc_minmax_cnt > agc_minmax_threshold)
{
/* During the last agc_minmax_threshold */
/* samples non of the samples appeared to be */
/* larger than the maximum value recorded in */
/* agc_extreme, so most likely a maximum has */
/* been found. Now continue searching for a */
/* minimum. */
agc_minmax_cnt = 0;
agc_minmax_state = 0x8000; /* Search minimum.*/
}
}
}
else
{
/* Searching for a minimum. */
if (stima < agc_minmax_extreme)
{
/* Record current sample as its value is smaller */
/* than the smallest seen value since searching */
/* for a minimum. */
agc_minmax_cnt = 0;
agc_minmax_extreme = stima;
}
else
{
/* Current sample value larger than the smallest */
/* seen value up to now. */
++agc_minmax_cnt;
if (agc_minmax_cnt > agc_minmax_threshold)
{
/* During the last agc_minmax_threshold */
/* samples non of the samples appeared to be */
/* smaller than the minimum value recorded */
/* in agc_extreme, so most likely a minimum */
/* has been found. */
/* Update the loop gain of the controller in */
/* question using the minimum value of stima */
/* and continue searching for maximum. */
agc_minmax_cnt = 0;
agc_minmax_state = 0x7fff; /* Search maximum.*/
--agc_minmax_nr_cycles;
/* Select coefficient bank of the controller */
/* on which the AGC procedure is currenty */
/* being performed. */
if (gainadj & 0x02)
{
/* AGC performed on tracking controller. */
agc_ctrl_coeff = coeff_tracking;
}
else
{
/* AGC performed on focus controller. */
agc_ctrl_coeff = coeff_focus;
}
/* Perform loop gain adjustment using the */
/* minimum value of stima, taking in account */
/* the compensation of the factor 4 introdu- */
/* ced during the stima calculation. */
agc_ctrl_coeff[10] *= agc_minmax_extreme;
if (agc_ctrl_coeff[10] < (fraction) 0x0800)
{
agc_ctrl_coeff[9] -= (fraction) 0x0002;
agc_ctrl_coeff[10] = agc_ctrl_coeff[10] << 4;
}
else if (agc_ctrl_coeff[10] < (fraction) 0x1000)
{
agc_ctrl_coeff[9] -= (fraction) 0x0001;
agc_ctrl_coeff[10] = agc_ctrl_coeff[10] << 3;
}
else if (agc_ctrl_coeff[10] < (fraction) 0x2000)
{
/* No overflow, factor 4 compensation. */
agc_ctrl_coeff[10] = agc_ctrl_coeff[10] << 2;
}
else if (agc_ctrl_coeff[10] >= (fraction) 0x4000)
{
/* Overflow will occure when perfoming */
/* the factor 4 compensation on c[15], */
/* use the shift gain c[14] to compen- */
/* sate. */
agc_ctrl_coeff[9] += (fraction) 0x0002;
}
else
{
/* Overflow will occure when performing */
/* factor 4 compensation only on c[15], */
/* divide compensation into a factor 2 */
/* for both c[15] and the shifting gain */
/* c[14]. */
agc_ctrl_coeff[9] += (fraction) 0x0001;
agc_ctrl_coeff[10] = agc_ctrl_coeff[10] << 1;
}
/* Change the dsp_state after every loop */
/* in order to send an event to ARM. */
/* This allows ARM to check whether or */
/* not the newly set value lies in the */
/* allowed range such the actuator coils do */
/* not become overheated. */
/* The two AGC state bits in dsp_state */
/* indicate on which control loop the gain */
/* was updated: 0x01 -> focus */
/* 0x03 -> tracking */
dsp_state = get_equ_agc(dsp_state, gainadj);
}
}
}
}
else
{
/* Turn the AGC procedure off when the loop gain has */
/* been adjusted as many times as was specified by the */
/* value in variable agc_minmax_nr_cycles. */
vib_gain = 0x0000;
gainadj = 0x0000;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -