📄 dsa.c
字号:
/* Copyright 1996, ESS Technology, Inc. *//* SCCSID @(#)dsa.c 4.30 03/15/05 *//* * $Log$ *//* * Removed SERVO..servo targets shall use separate "dsa" modules */ #include <stdio.h>#include <stdlib.h>#include <ctype.h>#include "vcxi.h"#include "buffer.h"#include "const.h"#include "cd.h"#include "debug.h"#include "display.h"#include "dsa.h"#include "micro.h"#include "tdm.h"#include "timedef.h"#include "util.h"#include "play.h"#include "av_play.h"#include "vscale.h"#include "xport.h"#include "vp.h"#include "echo.h"#ifdef TWO_FIELDS_OSD #include "cg.h"#else#include "fsosd.h"#endif#ifdef FRACTINT#include "fractint.h"#endif#ifdef MP3#include "mp3.h"#endif #ifdef ANTI_SHOCK#include "recorder.h"#endif /*------------------------------------------------------------------------ * Debugging macros *------------------------------------------------------------------------*/#ifdef DEBUG_OSDextern int osdreg;#define CPRINTF(a,b) {osdreg+=3;if(osdreg>13)osdreg=1;debug_osd(a,b,osdreg);}#else#define CPRINTF(a,b)#endif#if 0int bpt;#define BREAKPOINT(x) {bpt=x;while(bpt) VCX_service();}#else#define BREAKPOINT(x) #endif/************************************************************************ * DSA variables , for CD control * ************************************************************************/#ifndef CLEAR_DSA_ACK /* We'll get rid of this via config.h. *//* * In our hardware, AUX0 and AUX1 are open collector pads. * AUX2 and AUX3 are tristate which requires external pull-up resistors * for our application. * * We use * AUX0 as DSA ACK * AUX1 as DSA DATA * AUX3 as DSA STROBE */#define DSA_ACK 0x01 /* AUX0 is connected to ACK */#define DSA_DA 0x02 /* AUX1 is connected to DATA */#define DSA_ST 0x08 /* AUX3 is connected to STROBE */#define DSA_STEN 0x20 /* AUX3 is tristate, so this * * enables output. *//* Macros to set DSA output's value */#define CLEAR_DSA_ACK CLEAR_AUX0#define CLEAR_DSA_DATA CLEAR_AUX1#define CLEAR_DSA_STROBE CLEAR_AUX3#define SET_DSA_ACK TRISTATE_AUX0#define SET_DSA_DATA TRISTATE_AUX1#define SET_DSA_STROBE TRISTATE_AUX3/* Macros to evaluate DSA input's value */#define DSA_ACK_HIGH (mvd[riface_aux1] & DSA_ACK)#define DSA_DATA_HIGH (mvd[riface_aux1] & DSA_DA)#define DSA_STROBE_HIGH (mvd[riface_aux1] & DSA_ST)#define DSA_ACK_LOW (!DSA_ACK_HIGH)#define DSA_DATA_LOW (!DSA_DATA_HIGH)#define DSA_STROBE_LOW (!DSA_STROBE_HIGH)#endif /* CLEAR_DSA_ACK *//* dsa commands */#define DSA_STOP 0x02#define DSA_PAUSE 0x04#define DSA_PAUSERELEASE 0x05#define DSA_OPEN 0x0a#define DSA_CLOSE 0x0b#define DSA_GO_MIN 0x10#define DSA_GO_SEC 0x11#define DSA_GO_FRM 0x12#define DSA_LTOC 0x14 /* Long table of content */#define DSA_MODE 0x15#define DSA_GET_DISC_STATUS 0x50#define DSA_DAC 0x70#define DSA_ROTATE_CLOCKWISE 0x80#define DSA_ROTATE_ANTI_CLOCKWISE 0x81#define DSA_CLEARTOC 0x6a /* For CD7001 *//* servo commands */#define SERVO_FOUND 0x01#define SERVO_STOPPED 0x02#define SERVO_DISC_STATUS 0x03#define SERVO_ERROR 0x04#define SERVO_MOVING 0x0b#define SERVO_OPENED 0x0c#define SERVO_CLOSED 0x0d#define SERVO_TRACK 0x10#define SERVO_INDEX 0x11#define SERVO_MIN 0x12#define SERVO_SEC 0x13#define SERVO_MODE_STATUS 0x17#define SERVO_LTOC_TRACK 0x60#define SERVO_LTOC_CTL_ADR 0x61#define SERVO_LTOC_SMIN 0x62#define SERVO_LTOC_SSEC 0x63#define SERVO_LTOC_SFRM 0x64#define SERVO_DAC_STATUS 0x70#define SERVO_CAROUSEL_MOVING 0x80#define SERVO_CAROUSEL_STOPPED 0x81#define SERVOERR_NODISC 0x2#define SERVO_CLEARTOCED 0x6a /* For CD7001 */extern int vcd20_start, vcd20_end;/* DSA transmission state (tran_state) */#define D_IDLE 0#define D_SYNC01 1#define D_SYNC02 2#define D_SYNC03 3#define D_TRAN01 4#define D_TRAN02 5#define D_TRAN03 6#define D_ACK02 7/* DSA receiving state (rec_state) */#define R_IDLE 0#define R_W_SYNC1 1#define R_REC0 2#define R_REC1 3#define R_W_ACK0 4#define R_W_ACK1 5/************************************************************************ * Global variables * ************************************************************************/#ifdef SERVO_6003int disc_6003_status; /* 6003 disc status */int eject_6003_retry; /* Philips 6003 loader open/clese * * retry flag */int power_6003_timer = 0; /* power on/off delay time */#endifCDINFO CDinfo;int power_up = 1; /* Flag is set to 0 after system starts. */int num_of_track; /* # of tracks in the CD */int first_seg_ad; /* BCD sector location for first segment* * address. Comes from INFO.VCD. It is * * always in MM:SS:FF form. Should be * * XXYY00. In most case, XX is 00 and * * YY is 05 but there is no guarantee. * * (From INFO.VCD) */int CDinited = 0; /* 0: key info of CD has not been read * * 1: CD info has been read/stored */char forceDSAabort = 0;/* Force DSA to quit and return as if * * command succeed. */unsigned int err_code = 0; /* Error code from DSA routines */unsigned char servo_track_changed; /* A flag indicates a new track has come. */unsigned int servo_info=0; /* store TTIIMMSS info from servo. */unsigned int last_servo_info;/* store previous TTIIMMSS info from servo. */int currentTVmode; /* TV_NTSC or TV_PAL */int bcd_num_of_track; /* used in OSD */int save_ramcode = -1;unsigned char *CDI_ptr;/************************************************************************ * Variables local to this module * ************************************************************************/PRIVATE int dsa_flag; /* DSA flag. Indicate whether DSA * * transmission/reciving is completed. */PRIVATE int dsa_word; /* DSA result from servo */PRIVATE int dsa_rcv_mask; /* Mask for dsa_receive routine. */PRIVATE int tran_state = D_IDLE; /* trans_dsa state variable */PRIVATE int rec_state = R_IDLE; /* rec_dsa state variable */PRIVATE int currDSAmode = 0;/* Current CDROM's DSA mode. We'll only * * issue dsa_mode command if the new * * mode is different from the current * * mode. */PRIVATE unsigned int RDSATimeCount;PRIVATE unsigned int CDDA_play_time;PRIVATE unsigned int CDDA_track_start_time;#define DSA_GO_INIT 0#define DSA_GO_MINUTE 1#define DSA_GO_SECOND 2#define DSA_GO_FRAME 3#define DSA_GO_RECEIVE_INIT 4#define DSA_GO_RECEIVE 5#define DSA_GO_ALMOST_DONE 6int dsa_go_state = DSA_GO_INIT;IMPORT int DiscMode;/************************************************************************ * Debug variables * ************************************************************************/DEBUGVAR(go_time, 0); /* The last dsa_go time */DEBUGVAR(dbgDSAclose, 0); /* Debug variable for dsa_close routine */DEBUGVAR(dbgDSAgo, 0); /* Debug variable for dsa_go routine */DEBUGVAR(dbgDSAmode, 0); /* Debug variable for dsa_mode routine */DEBUGVAR(dbgDSAopen, 0); /* Debug variable for dsa_open routine */DEBUGVAR(dbgDSApause, 0); /* Debug variable for dsa_pause routine */DEBUGVAR(dbgDSApauserelease, 0);/* Debug variable for dsa_pauserelease */DEBUGVAR(dbgDSArelease, 0); /* Debug variable for dsa_release */DEBUGVAR(dbgDSArcv, 0); /* Debug variable for receive_dsa */DEBUGVAR(dbgDSAstop, 0); /* Debug variable for dsa_stop routine */#ifdef SERVO_7DEBUGVAR(dbgDSAcleartoc,0); /* Debug variable for dsa_cleartoc routine */#endifDEBUGVAR(dbgPlaySector, 0); /* Can't find the given sector from 20 * * frames ealier. */DEBUGVAR(dbgGetSector, 0); /* Can't get the sector (because SYNC * * pattern is not found). */DEBUGVAR(glbSec, 0); /* Global time in seconds */DEBUGVAR(dbgTransDsa, 0); /* Debug variable for trans_dsa */DEBUGVAR(dbgReceiveDsa, 0); /* Debug variable for receive_dsa */DEBUGVAR(dbgServiceVcxi, 0); /* Number of time service_vcxi is called*/DEBUGVAR(dbgSafeServiceVcxi, 0);/* Number of "save" service_vcxi calls */DEBUGVAR(dbgMaxRDSA, 0); /* Max. RDSATimeCount */DEBUGVAR(dbgMaxRcvAll, 0); /* Max. number of receive_dsa calls * * before we get a full piece of data */DEBUGVAR(dbgMaxRcvElapse, 0); /* Max. elapsed time for receive_dsa_all*/DEBUGVAR(dbgMaxTran, 0); /* Max. number of trans_dsa loop count */DEBUGVAR(dbgMaxTranElapse, 0); /* Max. elapsed time for trans_dsa */DEBUGVAR(dbgServoRcv, 0); /* receive_dsa_all time out */DEBUGVAR(dbgServoTran, 0); /* trans_dsa time out */DEBUGVAR(dbgMaxLtocCnt, 0); /* Max. number of LTOC replies *//************************************************************************ * Functions declared and used within this module only. * ************************************************************************/PRIVATE int dsa_go_step_by_step(unsigned int);PRIVATE void init_dsa(void);PRIVATE int receive_dsa_all(int);PRIVATE void trans_dsa(int, int);PRIVATE int processCDI(unsigned int *, int);PRIVATE void reset_dsa_go();int receive_dsa_all(int);/************************************************************************ * Imported functions * ************************************************************************/IMPORT void microEngine();IMPORT void DISP_cigam();IMPORT void DISP_naicigam();void CUST_init(){ vcx_cd_drive = CD_PHILIPS;#ifdef EXT_INPUT vcx_ext_format = CD_SONY;#endif vcx_xfer_mode = 5; }void dsa_reset(){ servo_info = 0;}/* * Service microcontroller, CD ROM (etc) */void CUST_background(){ /* * If the NTSC/PAL switch is changed, then change TV mode * accordingly. * * NOTE: Enable POLL_TV_SWITCH only if your system has * dedicated pin for TV switch. Don't enable POLL_TV_SWITCH * if the TV switch is shared(i.e. VFD). In that case, * the TV mode can only be detected at power-up. */#ifdef POLL_TV_SWITCH#ifdef DSC if ((!IS_POWER_DOWN))#endif { PREPARE_DETECTION; if (currentTVmode == TV_NTSC) { if (!DETECT_NTSC) { play_change_tv_mode(); } } else { if (DETECT_NTSC) { play_change_tv_mode(); } } }#endif /* POLL_TV_SWITCH */#ifdef SERVO_6003 /* Philips 6003 loader open setup */ if (eject_6003_retry == 2) { while (TRAY_SH_IS_LOW){ power_6003_timer++; if (power_6003_timer > 1000) { eject_6003_retry=1; } break; } while (TRAY_SH_IS_HIGH) { eject_6003_retry = 1; break; } } else { while (TRAY_SH_IS_HIGH) { break; } while (TRAY_SH_IS_LOW) { TRAY_STOP; if (eject_6003_retry == 1) { cd_opened ^= 1; } power_6003_timer=0; eject_6003_retry=0; break; } } /* Philips 6003 loader open setup end */#endif if (power_up) { /* if in power-down mode, avoid doing power-up stuff */ if (!IS_POWER_DOWN) { initMicroObject(); init_dsa();#if (defined MP3_LOGO && defined ENABLE_MP3)#ifndef NOLOGO /*moved here from top.c, for slideshow problems due to longjump*/ play_mp3_logo((int *)mp3logo, T_mp3logo_SZ>>2);#endif#ifndef MP3_LOGO_IN_SHARE /* show LOGO after play_mp3_logo() */ show_mpeg_still(0xe1, powerupScreen, T_powerupScreen_SZ>>2);#endif /* !MP3_LOGO_IN_SHARE */#endif /* MP3_LOGO */#ifdef SERVO_6003 /* Philips 6003 program */ power_6003_timer=0; disc_6003_status=1; TRISTATE_6003_EAUX; eject_6003_retry = 0; while (DISC_1_IS_HIGH){ ROTATE_CLOCK_MOVE; } while (CD_UP_IS_HIGH){ ROTATE_CLOCK_MOVE; } ROTATE_STOP; cd_opened = 1; eject_6003_retry = 2; TRAY_CLOSE;#endif initCD(); /* Customize your init CD routine */ } power_up = 0; /* Reset after initCD() */ /* * In case CD was in pause state when we powered down, we need to] * release it first. Otherwise, CD will not play!! * dsa_pauserelease(); PVu commented out..already in initCD() */ /* this line is added by Andy_ho, temp commented */ /* power_on = 0; */ } else { DEBUGINC(1, dbgServiceVcxi); receive_dsa();/* test_dsa();*/ DEBUGINC(1, dbgSafeServiceVcxi); DEBUGASSIGN(glbSec, (glbTimer / ((currentTVmode == TV_PAL) ? 50 : 60)));#ifdef TWO_FIELDS_OSD CG_service(1);#else OSD_schedule_check();#endif upper_state_machine(1);/* Customize your play state machine */ }}/************************************************************************ * Utility routines * ************************************************************************//* * Read "num" sectors into the start of the system buffer. This routine is * only called to get system information (not MPEG A/V data) * * Inputs: * begin: CD sector time in MMSSFF (each is in BCD) * num: number of CD sectors to copy. This number has to be * smaller than sys_buf_size/size. * dest: * non-zero: data to VBV * 0: data to ABV * * Return: * -2: force abort * -1: failed dsa_go() or servo problem * 0: if failed * 1: if successful */int getSectors(begin, num, dest)unsigned int begin;int num, dest;{ unsigned int dsatime, tmp; unsigned int next_time; int xfer_done; int counter; int timeout; /* target time check.. * make sure it's larger than Leadin + "adjustment". */ if (CDtime_check(begin) || (begin < 0x204)) return(0); begCDtime = begin; endCDtime = adjCDtime(begCDtime, logical2physical(num), 1); /* Set DSA_GO time to be 4d frames ealier than user specified */ dsatime = adjCDtime(begCDtime, 0x4, -1); /* Only change DSA mode if the current mode is not CDROM */ TDM_isCDDA = 0; /* Data is scrambled (as opposed to CDDA) */ XPORT_load_ucode((dest) ? DATA_PS : MP3_PS); dsa_mode(MODE_ATTI_REL | MODE_CDROM | MODE_SPEED_NORMAL); counter = 0; do { xfer_done = 0; if (counter >= 2) { DEBUGINC(1, dbgGetSector); err_code = ERR_GETSECTOR; return(0); } counter++; if (!dsa_go(dsatime)) { /* DSA_GO command failed */ if (counter >= 2) { DEBUGINC(1, dbgGetSector); return(-1); } else { counter++; continue; /* Time not specified, don't go */ } } system_reset(); system_start(); TDM_isCDDA = 0; XPORT_play20video(XPORT_OFFSET_GET_SECTOR, 2048); TDM_turn_on(); next_time = glbTimer + HALF_SECOND; timeout = 0; while (!TDM_found_begCDtime) { /* * There may not be any SYNC pattern (CDDA disk), so we'll * conclude that we are not getting the data if we have * been sitting here for .5 second */ if ((glbTimer > next_time) || (currCDtime > endCDtime)) { /* * Check one more time. In case CDI_get is cleared since * I checked it the last time. If we just turn off TDM, * then there is some chance that nobody will turn * TDM on again (because CDI_get is cleared) */ timeout = 1; /* adjust dsatime a bit for next retry */ dsatime = adjCDtime(dsatime, 0x7, -1); break; }#ifdef ECHO MIC_service();#endif } /* check if the data tranfer is done */ if (!timeout) { /* Timeout to avoid hanging */#ifdef FLASH_UPDATE /* we may use getsectors() for "big" files */ tmp = (num>>6 - num>>9); /* ~(num/75) */ tmp = ONE_SECOND + tmp*ONE_SECOND; next_time = glbTimer + tmp;#else next_time = glbTimer + HALF_SECOND;#endif /* FLASH_UPDATE */ do { if (forceDSAabort) return(-2);#ifdef ECHO MIC_service();#endif } while (XPORT_active && (glbTimer < next_time)); xfer_done = 1; TDM_found_begCDtime = 0; } } while (!xfer_done); /* Victor: Because TDM will set end_of_play when CD_end is reached. We will need to reset end_of_play here. It should be safe because when we are getting PSD means we are not playing any playitem. */ end_of_play = 0; return(1);}/* * Start playing from a given sector. There is no ending location! * Starting sector is specified in CD time format (i.e. MMSSFF where * each of MM/SS/FF is a BCD) * * This routine will always instruct the CD to go 10d frames earlier. * * Inputs: * begin: Starting CD sector time (in MMFFSS) * vstream: Video stream type (E0/E1/E2) * size: nonzero - Size of a CD sector (in bytes) * 0 - finish "step_by_step"..no init. * * Return: * 1: successful * 0: failure */int playSectors(begin, vstream, size)unsigned int begin, vstream;int size;{ int return_val; if (size) { XPORT_active = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -