📄 srvact.c
字号:
/******************************************************************************/
/* Function: track_on (state machine) */
/* */
/*! \brief provides low level functionalities for track closing
* \param void
* \return uint8; OK in case of track closing success
* TRACK_NOT_FOUND in case of track closing failure
* IN_PROGRESS in case of track closing in progress
* \remark
*/
/******************************************************************************/
RETVAL track_on(void)
{
RETVAL track_on_result;
track_on_result = check_servo(CHECK_TTM | CHECK_FOCUS | CHECK_HF);
if (track_on_result == OK)
{
track_on_result = IN_PROGRESS;
switch (track_on_state)
{
case STATE_1:
DEBUG_SERVO(("radial_on", 4, 0));
if (!short_jump_in_progress())
{
start_short_jump_for_tracking_reset();
track_on_state = STATE_2;
}
else
{
track_on_state = STATE_3;
}
break;
case STATE_2:
if (short_jump_stopped())
{
#if (1 == NLC_DELTA_ZERO_TRACK_ON)
nlc_set_delta(NLC_PHI_DELTA_OFF); /* Set NLC threshold to zero during closing of radial controller => high bandwidth. */
#endif
#if (1 == TRACK_ON_WITHOUT_I_ACTION)
dsp_write_ymem(COEFF_TRACKING_ADD + 1, 0); /* Switch off I-action of tracking controller. */
#endif
to_dsp_flags_pc(TRK_OFF);
RA_CTRL1.field.linear_te = 1; /* linear TE HW050701a */
dsp_write_xmem(MODE_ADD, TRK_MODE);
set_sledge_for_play();
#ifdef APM_PICKUP
SER_STEP_MODE.field.stepper_mode = 0x01; /* tracking mode (step-control) */
#endif
to_dsp_flags_pc(TRK_ON);
track_on_state = STATE_3;
}
break;
case STATE_3:
check_tracking_fsm_call(CHECK_TRACKING_CALLER_TRACK_ON_CMD);
start_timer(SERVO_FUNCTION_TIMER, (!short_jump_in_progress()) ? TRACKING_PRO_WAIT_TIMEOUT : TRACKING_PRO_WAIT_TIMEOUT_SHORT_JUMP);
track_on_state = STATE_4;
break;
case STATE_4:
if (tracking_ok())
{
dsp_write_xmem(BW_SWITCH_ADD, 0x4000);
if (!short_jump_in_progress())
{
RA_CTRL1.field.linear_te = 0; /* classic TE (E-F) HW050701a */
#if (1 == NLC_DELTA_ZERO_TRACK_ON)
nlc_set_delta(NLC_PHI_DELTA_ON); /* Return NLC threshold to default value after capturing track. */
#endif
#if (1 == TRACK_ON_WITHOUT_I_ACTION)
dsp_write_ymem(COEFF_TRACKING_ADD + 1, TRACKING_PRO_CONTROLLER_COEFF[1]); // Turn on I-action of tracking controller, TODO: Get value from profile.
#endif
}
track_on_result = OK;
}
else if (!timer_in_progress(SERVO_FUNCTION_TIMER))
{
to_dsp_flags_pc(TRK_OFF);
#ifndef APM_PICKUP
sledge_idle();
#endif
RA_CTRL1.field.linear_te = 0; /* classic TE (E-F) HW050701a */
start_timer(SERVO_FUNCTION_TIMER, TRACKING_PRO_RETRY_TIMEOUT_OFFSET + DEF_TRACKING_PRO_RETRY_TIMEOUT_DITHER * tracking_recover_dither_counter);
tracking_recover_dithering();
track_on_state = STATE_5;
}
break;
//case STATE_5:
default:
if (!timer_in_progress(SERVO_FUNCTION_TIMER))
{
track_on_result = TRACKING_NOT_FOUND;
}
break;
}
}
/* else not needed ((track_on_result = check_servo(CHECK_TTM | CHECK_FOCUS | CHECK_HF)) == TTM_STOPPED / FOCUS_LOST / HF_LOST) */
return track_on_result;
}
/******************************************************************************/
/* Function: track_closing (state machine) */
/* */
/*! \brief provides track closing "on the place" (not after jump)
* \param void
* \return uint8; OK in case of track closing success
* TRACK_NOT_FOUND in case of track closing failure
* IN_PROGRESS in case of track closing in progress
* \remark
*/
/******************************************************************************/
RETVAL track_closing(void)
{
RETVAL track_closing_result;
if ((track_closing_state != STATE_1) && (!timer_in_progress(SERVO_SAFETY_TIMER)))
{
track_closing_result = TRACK_CLOSING_TIMEOUT_ERROR;
}
else
{
track_closing_result = IN_PROGRESS;
switch (track_closing_state)
{
case STATE_1:
DEBUG_SERVO(("radial_on", 4, 0));
start_timer(SERVO_SAFETY_TIMER, TRACKING_PRO_CLOSING_TIMEOUT);
track_closing_state = STATE_2;
break;
case STATE_2:
track_closing_result = track_on();
break;
}
}
return track_closing_result;
}
/******************************************************************************/
/* Function: track_off */
/* */
/*! \brief provides track opening
* \param void
* \return uint8
* \remark
*/
/******************************************************************************/
void track_off(void)
{
DEBUG_SERVO(("radial_off", 4, 0));
check_tracking_fsm_call(CHECK_TRACKING_CALLER_TRACK_OFF_CMD);
if (!short_jump_in_progress())
{
to_dsp_flags_pc(TRK_OFF);
dsp_write_xmem(MODE_ADD, ADJ_MODE);
#ifndef APM_PICKUP
sledge_idle();
#endif
#ifdef APM_PICKUP
/* Reduce stepper gain for offtrack situation */
SER_STEP_CTRL.field.scale_factor = 0x01;
#endif
}
}
/******************************************************************************/
/* Function: reset_loop_values */
/* */
/*! \brief provides automatic gain control for focus or tracking loop
* \param uint8 loop (AGC_FOCUS_LOOP/AGC_TRACKING_LOOP)
* \return
* \remark
*/
/******************************************************************************/
void reset_loop_values(uint8 loop) /* BB041013b */
{
if (AGC_FOCUS_LOOP == loop)
{
dsp_write_ymem(FOCUS_GAIN_ADD, AGC_PRO_GAIN_FOCUS);
dsp_write_ymem(FOCUS_SHIFT_GAIN_ADD, FOCUS_PRO_CONTROLLER_COEFF[FOCUS_SHIFT_GAIN_INDEX]);
}
else
{
dsp_write_ymem(TRACKING_GAIN_ADD, AGC_PRO_GAIN_TRACKING);
dsp_write_ymem(TRACKING_SHIFT_GAIN_ADD, TRACKING_PRO_CONTROLLER_COEFF[TRACKING_SHIFT_GAIN_INDEX]);
}
}
/******************************************************************************/
/* Function: agc (state machine) */
/* */
/*! \brief provides automatic gain control for focus or tracking loop
* \param uint8 loop (AGC_FOCUS_LOOP/AGC_TRACKING_LOOP)
* \return uint8; OK in case of AGC success
* FOCUS_LOST/HF_LOST/TRACKING_LOST in case of servo failures
* \remark the gain value, calculated by this routine, is stored in
* focus_gain or tracking_gain variable
*/
/******************************************************************************/
RETVAL agc(uint8 loop)
{
RETVAL agc_result;
if ((agc_state != STATE_1) && (!timer_in_progress(SERVO_SAFETY_TIMER)))
{
if (loop == AGC_FOCUS_LOOP)
{
agc_result = AGC_FOCUS_TIMEOUT_ERROR;
}
else /* (loop == AGC_TRACKING_LOOP) */
{
agc_result = AGC_TRACKING_TIMEOUT_ERROR;
}
}
else if (((loop == AGC_FOCUS_LOOP) && (servo_startup_flags.field.agc_focus_done))
|| ((loop == AGC_TRACKING_LOOP) && (servo_startup_flags.field.agc_tracking_done)))
{
agc_result = OK;
}
else if (dsp_error_flags.field.agc_focus_error
|| dsp_error_flags.field.agc_tracking_error) /* BB041013b */
{
dsp_error_flags.field.agc_focus_error = 0;
dsp_error_flags.field.agc_tracking_error = 0;
reset_loop_values(loop);
if (AGC_FOCUS_LOOP == loop)
{
agc_result = AGC_FOCUS_ERROR;
}
else
{
agc_result = AGC_TRACKING_ERROR;
}
stop_timer(SERVO_FUNCTION_TIMER);
}
else
{
//MR041215 quick fix TODO agc_result = check_servo(CHECK_TTM | CHECK_FOCUS | CHECK_HF | CHECK_TRACKING);
agc_result = check_servo(CHECK_TTM | CHECK_FOCUS);
if (agc_result == OK)
{
agc_result = IN_PROGRESS;
switch (agc_state)
{
case STATE_1:
{
uint8 coeff_index;
uint8 dsp_addr;
/* NLC automatically turned off in DSP during AGC */ /* nlc_off(); */ /* to be sure that nonlinear ctrl is off */
/* Make sure the AGC procedure is turned off. */
dsp_write_xmem(GAINADJ_ADD, AGC_NO_INJECTION);
/* Initialize the parameters controlling the search for the correct loop gain adjustment. */
dsp_write_xmem(AGC_MINMAX_NR_CYCLES_ADD, AGC_PRO_MINMAX_NR_CYCLES);
dsp_write_xmem(AGC_MINMAX_THRESHOLD_ADD, AGC_PRO_MINMAX_THRESHOLD);
/* Set coefficient index for focus/tracking. */
dsp_addr = COEFF_MISC_ADD;
if (loop == AGC_FOCUS_LOOP)
{
for (coeff_index = 0; coeff_index < 8 ; coeff_index++, dsp_addr++)
{
dsp_write_ymem(dsp_addr, AGC_PRO_COEFF_FOCUS[coeff_index]);
}
/* Turn on AGC procedure */
dsp_write_xmem(GAINADJ_ADD, AGC_INJECTION_ON_FOCUS);
dsp_write_xmem(VIB_GAIN_ADD, AGC_PRO_INJECTION_FOCUS_AMPLITUDE);
}
else /* (loop == AGC_TRACKING_LOOP) */
{
for (coeff_index = 0; coeff_index < 8 ; coeff_index++, dsp_addr++)
{
dsp_write_ymem(dsp_addr, AGC_PRO_COEFF_TRACKING[coeff_index]);
}
/* Turn on AGC procedure */
dsp_write_xmem(GAINADJ_ADD, AGC_INJECTION_ON_TRACKING);
dsp_write_xmem(VIB_GAIN_ADD, AGC_PRO_INJECTION_TRACKING_AMPLITUDE);
}
/* Set time-out after which will be checked whether or not the AGC procedure has finished. */
start_timer(SERVO_FUNCTION_TIMER, AGC_PRO_WAIT_TIMEOUT);
start_timer(SERVO_SAFETY_TIMER, AGC_PRO_TIMEOUT);
agc_state = STATE_2;
}
break;
case STATE_2:
if (!timer_in_progress(SERVO_FUNCTION_TIMER))
{
agc_state = STATE_3;
}
break;
//case STATE_3:
default:
if (dsp_read_xmem(AGC_MINMAX_NR_CYCLES_ADD) == 0) /* Check whether AGC is finished or not. */
{
/* AGC finished. */
if (loop == AGC_FOCUS_LOOP)
{
servo_startup_flags.field.agc_focus_done = 1;
}
else /* (loop == AGC_TRACKING_LOOP) */
{
servo_startup_flags.field.agc_tracking_done = 1;
#ifndef APM_PICKUP
if (!servo_startup_flags.field.first_startup_sequence_completed)
{
store_hostif_servo_parameters(HSP_STORING_MODE_STARTUP_OK);
}
#ifndef EXECUTE_AGC_ONLY_ONCE
else
{
store_hostif_servo_parameters(HSP_STORING_MODE_RESTART_OK);
}
#endif
#endif
}
agc_result = OK;
}
/* else not needed */
break;
}
}
else /* ((agc_result = check_servo(CHECK_TTM | CHECK_FOCUS | CHECK_HF | CHECK_TRACKING)) == TTM_STOPPED / FOCUS_LOST / HF_LOST / TRACKING_LOST) */
{
reset_loop_values(loop); /* BB041013b */
}
}
return agc_result;
}
#endif // HAVE_CD_MECHA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -