📄 toc.c
字号:
/************************************************** * * toc.c * * CVS ID: $Id: toc.c,v 1.32 2007/09/19 07:40:46 belardi Exp $ * Author: Fabio Dell'Orto [FD] - STM * Date: $Date: 2007/09/19 07:40:46 $ * Revision: $Revision: 1.32 $ * * Description: * * *************************************************** * * COPYRIGHT (C) ST Microelectronics 2005 * All Rights Reserved * ******************************************************************************* * \brief TOC reading state machine * * \par Change History: * * - HW060202a Workarround for disk detection after Reset and new startup * and disk is already spinning * - HW060309a Fixed CDI disc subcode count retrys * **************************************************** * * STM CVS Log: * * $Log: toc.c,v $ * Revision 1.32 2007/09/19 07:40:46 belardi * New config option to disable multisession for copy-protected CD * * Revision 1.31 2007/07/31 12:00:15 belardi * Removed compiler warning * * Revision 1.30 2007/04/11 14:19:14 belardi * Integration of HAVE_CD_MECHA modification by [GP] * * Revision 1.29 2007/04/06 06:34:23 hara * Put more robust TOC reading sequence (perform next session reading if the sector is not Mode1). * * Revision 1.28 2006/11/25 08:10:46 belardi * Ununsed function removal to free code space * * Revision 1.27 2006/10/31 11:11:57 marcucci * No more static functions for Jump Table * * Revision 1.26 2006/10/17 09:48:01 trubac * set_dummy_toc - data track * * Revision 1.25 2006/09/18 09:55:21 belardi * Corrected CVS keyword usage * * Revision 1.24 2006/09/18 09:22:36 belardi * Added Log CVS keyword into file header * * Revision 1.23 2006/09/15 20:17:25 belardi * Added Log CVS keyword into file header * * ******************************************************************************/#include "gendef.h"#include "hwreg.h"#include "osal.h"#include "srvinc.h"#include "controller.h" // [RB]#if (1==HAVE_CDTEXT)#include "text.h"#endif/* Local defines */#define CDI_WORKAROUND#define DISKSIZE_WORKAROUND//#define TOC_READ_JUMP_TO_STARTtypedef struct{ uint8 min_track; uint8 max_track; uint8 num_of_audio_track; uint32 T_next_program_area; uint8 Tmsf_lead_out[3]; uint8 type; uint8 control; uint8 flags; uint8 warnings;} SESSION_STRUCT;static SESSION_STRUCT session;static uint32 T_program_area;static uint8 last_min_track;static uint8 toc_state_tmp;static uint8 toc_sm_state[2];static RETVAL toc_error_reason;static uint8 track_read;static uint8 toc_retries;static int16 subcode_counter;static uint8 toc_session_count;uint8 toc_state;TOC_DATA_STRUCT TOC_data;uint16 CDinfo;#define toc_q_cadr CAPTURE_SUBCODE.q_subcode.q_cadr#define toc_q_tno CAPTURE_SUBCODE.q_subcode.q_tno#define toc_q_point CAPTURE_SUBCODE.q_subcode.q_point#define toc_q_min CAPTURE_SUBCODE.q_subcode.q_min#define toc_q_sec CAPTURE_SUBCODE.q_subcode.q_sec#define toc_q_frame CAPTURE_SUBCODE.q_subcode.q_frame#define toc_q_zero CAPTURE_SUBCODE.q_subcode.q_zero#define toc_q_pmin CAPTURE_SUBCODE.q_subcode.q_amin#define toc_q_psec CAPTURE_SUBCODE.q_subcode.q_asec#define toc_q_pframe CAPTURE_SUBCODE.q_subcode.q_aframe#define COPY_PROTECTION_ENABLED (module_config.data.hybrid_disc_cfg.field.disable_cp_check == 0)#define MULTISESSION_ENABLED (module_config.data.hybrid_disc_cfg.field.disable_multisession == 0)#define SESSION_MAX_TRACK (session.max_track)#define SESSION_MIN_TRACK (session.min_track)#define SET_SESSION_MAX_TRACK(x) do{ session.max_track = bcd_2_hex(x); } while(0)#define SET_SESSION_MIN_TRACK(x) do{ session.min_track = bcd_2_hex(x); } while(0)#define SESSION_LEAD_OUT_TIME() msf_2_sid(session.Tmsf_lead_out[MIN], \ session.Tmsf_lead_out[SEC], \ session.Tmsf_lead_out[FRAME], HEX)#define SET_SESSION_LEAD_OUT(_min,_sec,_frm) do{ \ session.Tmsf_lead_out[MIN] = bcd_2_hex(_min); \ session.Tmsf_lead_out[SEC] = bcd_2_hex(_sec); \ session.Tmsf_lead_out[FRAME] = bcd_2_hex(_frm); \ } while(0)TOC_FLAGS_UNION toc_flags;uint32 toc_get_track_time(uint8 track){ return msf_2_sid((uint8)(TOC_data.track_data.min[track - 1] & 0x7F), (uint8)(TOC_data.track_data.sec[track - 1] & 0x7F), (uint8)(TOC_data.track_data.frame[track - 1] & 0x7F), HEX);}/******************************************************************************//* Function: set_jump_parameters *//* *//*! \brief * \param * \return * \remark *//******************************************************************************/void set_jump_parameters(uint32 _seek_mode, uint32 _target_time, sint16 _extra_tracks){ t_cap_cmd_event cap_cmd_event; cap_cmd_event.did = DEV_CD_ID; cap_cmd_event.command = CAP_CMD_TOC_JUMP; cap_cmd_event.command_params.toc_jump_params.seek_mode = _seek_mode; cap_cmd_event.command_params.toc_jump_params.target_time = _target_time; cap_cmd_event.command_params.toc_jump_params.extra_tracks = _extra_tracks; cap_cmd(&cap_cmd_event);}/******************************************************************************//* Function: reset_toc_state_vars *//* *//*! \brief * \param void * \return void * \remark *//******************************************************************************/void reset_toc_state_vars(void){ toc_flags.field.toc_fsm_started = 0; toc_flags.field.wait_for_set_speed = 0; toc_state = TOC_IDLE; toc_sm_state[LEVEL_0] = STATE_1; toc_sm_state[LEVEL_1] = STATE_1;}/******************************************************************************//* Function: reset_toc *//* *//*! \brief * \param reset flags * \return void * \remark *//******************************************************************************/void reset_toc(uint8 flags){ if (flags & TOC_RESET_TOC_READING) { last_min_track = 0xFF; CDinfo &= (LOW_REFLECTIVE | DISC_12CM | DISC_8CM); toc_flags.field.reading_first_toc = 1; toc_session_count = 1; reset_toc_state_vars(); } if (flags & TOC_RESET_CALIB_JUMP) { //disc_C = STARTING_DISC_C; //disc_R = STARTING_DISC_R; //disc_R2 = STARTING_DISC_R2; //trk_2_step = STARTING_TRK_2_STEP; }}/******************************************************************************//* Function: stop_toc *//* *//*! \brief * \param void * \return void * \remark *//******************************************************************************/void stop_toc(void){ if (!(CDinfo & ALL_TOC_READ)) { reset_toc(TOC_RESET_TOC_READING); } if (TOC_IDLE != toc_state) { reset_toc_state_vars(); }}/******************************************************************************//* Function: toc_check_read_position *//* *//*! \brief returns IN_PROGRESS if position correct * \param void * \return RETVAL * \remark *//******************************************************************************/RETVAL toc_check_read_position(t_bool reading_first_toc){ if (reading_first_toc) { if (((toc_q_cadr & 0x0F) == MODE1) && (toc_q_tno != 0x00)) { if (toc_retries != 0) { set_jump_parameters(JUMP_TARGET_PLUS_TRACKS, CDT_2SEC, TRACKS_INTO_FIRST_LEADIN); return TOC_REQUEST_WAIT_FOR_SERVO; } else { return ERROR_ACCESS_TOC; } } } else // (!reading_first_toc) { if (0 == (CAPTURE_SUBCODE.event_type & _EVENT_TEP_HAD_TIME_BEFORE)) { return TOC_REQUEST_WAIT_FOR_TIME; } else if ((CAPTURE_SUBCODE.T_actual < (T_program_area - CDT_32SEC)) || (CAPTURE_SUBCODE.T_actual >= T_program_area)) { if (toc_retries != 0) { set_jump_parameters(JUMP_TARGET_1, (T_program_area - CDT_30SEC), NO_SKIP); return TOC_REQUEST_WAIT_FOR_SERVO; } else // toc_retries = 0 { return ERROR_ACCESS_TOC; } } else if (((toc_q_cadr & 0x0F) == MODE1) && (toc_q_tno != 0)) { return ERROR_TOC_NOT_FOUND; } } return IN_PROGRESS;}/******************************************************************************//* Function: toc_read_subcode *//* *//*! \brief when a new subcode is ready from acquisition, it is parsed * to collect TOC information * \param void * \return * \remark *//******************************************************************************/RETVAL toc_read_subcodes(void){ RETVAL toc_read_subcodes_result; toc_read_subcodes_result = toc_check_read_position((t_bool) toc_flags.field.reading_first_toc); if ((toc_q_tno == 0) && (toc_read_subcodes_result == IN_PROGRESS)) { switch (toc_q_cadr & 0x0F) { case MODE1: if ((toc_flags.field.reading_first_toc) && (toc_q_min >= 0x95)) { CDinfo |= MS_R_RW; } switch (toc_q_point) { case 0xA0: // min track on disc if ((session.flags & MIN_TRACK_FOUND) == 0) { session.flags |= MIN_TRACK_FOUND; SET_SESSION_MIN_TRACK(toc_q_pmin); session.type = toc_q_psec; } break; case 0xA1: // max track on disc if ((session.flags & MAX_TRACK_FOUND) == 0) { session.flags |= MAX_TRACK_FOUND; SET_SESSION_MAX_TRACK(toc_q_pmin); session.control = (uint8)(toc_q_cadr & 0xF0); } break; case 0xA2: // lead_out time if ((session.flags & LEAD_OUT_FOUND) == 0) { session.flags |= LEAD_OUT_FOUND; SET_SESSION_LEAD_OUT(toc_q_pmin, toc_q_psec, toc_q_pframe); } break; default: // time info for each track (up to 99 tracks) if ((0 < toc_q_point) && (toc_q_point <= 0x99)) { uint8 hex_toc_q_point; hex_toc_q_point = bcd_2_hex(toc_q_point); if (TOC_data.track_data.min[hex_toc_q_point - 1] == 0xff) { if (toc_q_cadr & 0x40) { CDinfo |= HAVE_DATA_TRACK; } else { session.num_of_audio_track++; CDinfo |= HAVE_AUDIO_TRACK; } TOC_data.track_data.min[hex_toc_q_point - 1] = bcd_2_hex(toc_q_pmin); TOC_data.track_data.sec[hex_toc_q_point - 1] = bcd_2_hex(toc_q_psec); TOC_data.track_data.frame[hex_toc_q_point - 1] = bcd_2_hex(toc_q_pframe); if (toc_q_cadr & 0x40) { TOC_data.track_data.min[hex_toc_q_point - 1] |= 0x80; } if (toc_q_cadr & 0x10) { TOC_data.track_data.sec[hex_toc_q_point - 1] |= 0x80; } track_read = (uint8)(track_read + 1); } } else { session.warnings |= UNSUPPORTED_MOD1_POINT; } break; } if (((session.flags & ALL_TRACK_FOUND) == 0) && (session.flags & MIN_TRACK_FOUND) && (session.flags & MAX_TRACK_FOUND) && (track_read > (SESSION_MAX_TRACK - SESSION_MIN_TRACK))) { session.flags |= ALL_TRACK_FOUND; } break; case MODE5: session.flags |= MODE_5_FOUND; switch (toc_q_point) { case 0xB0: if ((session.flags & B0_FOUND) == 0) { CDinfo |= MULTISESSION; session.flags |= B0_FOUND; if (toc_q_min != 0xff) { session.flags |= NEXT_SESSION; session.T_next_program_area = msf_2_sid(toc_q_min, toc_q_sec, toc_q_frame, BCD); } } break; case 0xC0: session.flags |= C0_FOUND; break; default: session.warnings |= UNSUPPORTED_MOD5_POINT; break; } break; case MODE2: session.warnings |= MODE_2_FOUND; break; default: session.warnings |= UNSUPPORTED_MODE; break; } if ((session.flags & MIN_TRACK_FOUND) && (session.flags & MAX_TRACK_FOUND) && (session.flags & LEAD_OUT_FOUND) && (session.flags & ALL_TRACK_FOUND)#if (1==HAVE_CDTEXT) && (text_get_status() != BUSY)#endif ) { toc_read_subcodes_result = OK; } else {/* HW060309a - BEGIN */#ifdef CDI_WORKAROUND /* PRS0336 */ /* we miss some TOC information, but have enough information to decrease subcode_counter */ if ( (session.type == 0x10) /* Only for CDI-CD's */ && (0 == (session.flags & ALL_TRACK_FOUND)) && (session.flags & MIN_TRACK_FOUND) && (session.flags & MAX_TRACK_FOUND) && (session.flags & LEAD_OUT_FOUND)#if (1 == HAVE_CDTEXT) && (text_get_status() != BUSY)#endif ) { if (subcode_counter > (((SESSION_MAX_TRACK - SESSION_MIN_TRACK) + 1) * 6)) { subcode_counter = (((SESSION_MAX_TRACK - SESSION_MIN_TRACK) + 1) * 6); } }#endif/* HW060309a - END */ subcode_counter--; // if subcode timeout is EXPIRED and we miss some TOC info... retry OR error if (subcode_counter <= 0) /* HW060309a */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -