dsc.c

来自「ESS3890+SL原代码(1*16内存)」· C语言 代码 · 共 1,030 行 · 第 1/2 页

C
1,030
字号
/* Copyright 1997, ESS Technology, Inc.					*//* SCCSID @(#)dsc.c	4.16.1.4 01/18/05 *//* * This is to be shared with GAME */#include "vcxi.h"#include "ir.h"#include "util.h"#ifdef ECHO#include "echo.h"#endif#include "low.h"#include "const.h"#ifdef DSC/* * New 3881/3883 special AUX pin assignments: * EAUX6:	VFD data out.	  Serial port 1 data out  (better not to use) * EAUX7:	VFD data in.	  Serial port 1 data in   (better not to use) * EAUX8:	VFD clock output. Serial port 1 clock out (better not to use) * EAUX9:	SQSO (SQDT).	  Serial port 2 data in. * EAUX10:	SQCK.		  Serial port 2 clock out. * EAUX11:	IRQ out.	  Interrupt output to 3210/3220. * EAUX12:	C2PO.		  Interrupt input from CDROM (optional). * EAUX13:	16550.		  Interrupt input from 16550 (optional). * EAUX14:	S0S1.		  Interrupt input from subQ code (optional). * EAUX15:	IR.		  Interrupt input from remote control. * (for ES3890 only below) * EAUX16:	Gamepad CLK	   * EAUX17:	Gamepad LATCH * EAUX18:	Gamepad2 DATA *//************************************************************************ * Local defines.							* ************************************************************************/#ifdef NO_ZERO_MUTE#define ZERO_MUTE_BIT	0x00#else#define ZERO_MUTE_BIT	0x40#endif#ifdef IO3890/* video DACs power-down bit is inverted on ES3890 *//*  * DSC_VIDEO_ON is most likely OK for S-video as well because C input of TV * usually has a filter to get chroma signal. */#define DSC_VIDEO_ON		DSC_cmd(dsc_dvectl3, 0x0)   /* Y+V	*/#define DSC_VIDEO_OFF		DSC_cmd(dsc_dvectl3, 0x1)   /* All off	*/#define DSC_COMPOSITE_ONLY	DSC_cmd(dsc_dvectl3, 0x2)   /* V only	*/#else#define DSC_VIDEO_ON		DSC_cmd(dsc_dvectl3, 0x1)   /* Y+C+V	*/#define DSC_VIDEO_OFF		DSC_cmd(dsc_dvectl3, 0x0)   /* All off	*/#define DSC_COMPOSITE_ONLY	DSC_cmd(dsc_dvectl3, 0x7)   /* V only	*/#endif /* IO3890 *//************************************************************************ * Following defines are valid for 3207VA or later chips.		* ************************************************************************/#ifdef DSC_DITHER#define	AUDIORCV1_DITHER	0x4	/* This is no good. Don't use it*/#else#define	AUDIORCV1_DITHER	0#endif#ifdef DSC_SW_DETECT_CENTER#define	AUDIOADC2_RESET		0x40		/* Old style		*/#else#define	AUDIOADC2_RESET		0		/* Don't ever reset, it	*						 * affects ref. voltage.*/#endif/************************************************************************ * Following defines are valid for 3881 or later chips.			* ************************************************************************/#ifdef DSC_IRQ#define	DSC_CCHIP_CTL_IR_EN	0x40#else#define	DSC_CCHIP_CTL_IR_EN	0#endif/************************************************************************ * Private functions.							* ************************************************************************/PRIVATE void	DSC_init_irq_ctl(int, int, int, int, int);/************************************************************************ * Variables used in this module only.					* ************************************************************************/PRIVATE	unsigned int	shadow_eaux0_dat;	/* Shadow for dsc_aux0_dat */PRIVATE	unsigned int	shadow_eaux1_dat;	/* Shadow for dsc_aux1_dat */PRIVATE	unsigned int	shadow_eaux0_ctl;	/* Shadow for dsc_aux0_ctl */PRIVATE	unsigned int	shadow_eaux1_ctl;	/* Shadow for dsc_aux1_ctl */#ifdef IO3890PRIVATE	unsigned int	shadow_eaux2_dat;	/* Shadow for dsc_aux2_dat */PRIVATE	unsigned int	shadow_eaux2_ctl;	/* Shadow for dsc_aux2_ctl */#endif#ifdef DSC_IRQPRIVATE	unsigned int	shadow_irq_ctl;		/* Shadow for dsc_irq_ctl  */PRIVATE	unsigned int	shadow_aux_mode;	/* Shadow for dsc_aux_mode */#endif#ifdef SVIDEO_SELECTunsigned char svideo_setting;#endifPRIVATE	unsigned int	shadow_audioxmt1;	/* Shadow of audioxmt1	  */PRIVATE	unsigned int	shadow_cchip_ctl;	/* Shadow of dsc_cchip_ctl*//*  * This routine has to be called before all DSC routine. * * This routine will set DSC select. Then it will only be toggled in * timer interrupt. */void DSC_getstatus(){    int tmp, tmp1;    DSC_toggle();    if (((shadow_cchip_ctl = DSC_cmd(dsc_cchip_ctlm, 0)) >> 4) & 1) {	/* Warm boot */	if ((tmp = DSC_cmd(dsc_clkctlm, 0)) & 1) 	{	    /* Already running at full speed */	    DSC_status = DSC_STATUS_RUNNING;	} else {	    DSC_status = DSC_STATUS_STANDBY;#ifdef IR	    /* Read the code into cache so we can run at lower speed! */#ifdef DSC_IRQ	    IR_recv_interrupt_service(0);#else	    IR_recv_interrupt_service();#endif#endif	    /* Running at 1/8th of full speed */	    mvd[riface_width] = 0x81;	    asm("nop");	    asm("nop");	    /* B0,B3: 0 WS and B1,B2: 32 WS */	    mvd[riface_wait_state] = 0x1f801f; 	}#ifdef IR_PHILIPS	IR_ctlbit = (tmp >> 1) & 1;	/* Get the last control bit	*/#endif    } else {#ifdef IGNORE_POWERDOWN	DSC_status = DSC_STATUS_RUNNING;#else	DSC_status = DSC_STATUS_ACON;#endif#ifdef IR_PHILIPS	IR_ctlbit = 2;	/* I.e. Any control bit will do. This is the	*			 * best setting if someone wants ACON to be ON	*/#endif    }}/* * Toggle DSC_S (a convention to tell 3207 that 3210 is still alive, so * it will not be reset accidentally.) * * We can't toggle DSC_S in the middle of communication, and this * routine is called mostly inside timer interrupt handler. Originally, * we have a semaphore to prevent calling this while communicating * with 3207. The new mechanism will disable any interrupt while * communicating with 3207, so semaphore is no longer needed. */void DSC_toggle(){    DSC_DESELECT;    DSC_SELECT;}/* * Send DSC command from 3208/3210 to 3207 *	dcs_c:	CS1 *	dsc_s:	AUX3 *	d[7:0]:	data[7:0] * DSC data space is at address 0x14000003 (i.e. assert CS1) */unsigned int DSC_cmd(addr, data)unsigned int addr;unsigned int data;{    volatile unsigned char *prt;    volatile unsigned int *ptrdelay = (unsigned int *) bank3safe;       /*      * Disable interrupt while communicating with 3207 such address     * and data can always be in pair.     */    mvd[riface_irqsuppress] = 0;    asm("nop");    prt = DSC_ADDRESS;    /* asserting dsc strobe from 3210 */    *prt = addr;    (void) *ptrdelay;    if (!(addr & 0x1)) {	*prt = data;	data = 0;    } else data = *prt;    return(data);} /* * Reset 3207 to make sure left/right channel is not swapped. */void DSC_reset_audio(){#ifdef IO3890     /* no internal audio DAC */    /* Need to set these two registers to improve SNR */    DSC_cmd(dsc_audiorcv1, 0xc0);    DSC_cmd(dsc_audiorcv2, 0x08);#else#ifdef ES3207A    int i;    volatile unsigned int *ptrdelay = (unsigned int *) bank3safe;#endif    /* Reset 3207 so it will start from the left channel */    shadow_cchip_ctl &= ~2;		/* Disable 07 audio DAC		*/    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);    DSC_cmd(dsc_audiorcv1, 0x80 | AUDIORCV1_DITHER);					/* Reset 07 audio recv		*/    DSC_cmd(dsc_audiorcv1, 0x90 | AUDIORCV1_DITHER);					/* Enable 07 audio recv		*/    shadow_cchip_ctl |= 2;		/* Enable 07 audio DAC		*/    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);#ifdef ES3207A    for (i = 0; i < 10000; i++) (void) *ptrdelay;    shadow_cchip_ctl &= ~0x20;	        /* Turn off mute */    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);#endif#endif /* IO3890 */}#ifdef ECHOvoid DSC_mic_on(void){    int i;    unsigned int adc2;    volatile unsigned int *ptrdelay = (unsigned int *) bank3safe;#ifdef MIC_RECORD    adc2 = 0x24;	/* Add 6dB gain for even 3883 for mic record 	*/#else    adc2 = 0x20;		/* NO 6dB gain				*/#endif#ifndef IO3890    if (ECHO_analog_bypass) {	adc2 |= 0x8;			/* Add MIC input to speaker out	*/	/*	 * Why doing analog by-pass, it is possible that there is no	 * data from 3880 (e.g. MIC on but no echo and no CD data). In	 * which case, if we have zero_mute, then there won't be any audible	 * output!	 */#ifndef NO_ZERO_MUTE	shadow_audioxmt1 &= 0xbf;	/* Disable zero_mute 		*/	DSC_cmd(dsc_audioxmt1, shadow_audioxmt1);#endif    }    DSC_cmd(dsc_audioadc1, 0x08);#else#if (!defined(DSC_AUDIOCLK) && !defined(AUDIOCLK) && defined(FS384))    DSC_cmd(dsc_audioadc1, 0x0c);#else    DSC_cmd(dsc_audioadc1, 0x0b);#endif#endif /* IO3890 */    shadow_cchip_ctl |= 0x4;	     /* Enable MIC ports		*/    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);    /* Delay some time so cap. can be charged up. */    for (i = 0; i < 20; i++) (void) *ptrdelay;    DSC_cmd(dsc_audioadc2, 0x00 | AUDIOADC2_RESET);				     /* cause soft reset adc		*/    DSC_cmd(dsc_audioadc2, adc2);}void DSC_mic_off(void){    shadow_cchip_ctl &= ~4;		/* Disable MIC ports		*/    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);    DSC_cmd(dsc_audioadc2, 0x00 | AUDIOADC2_RESET);				    /* cause soft reset adc		*/#ifndef NO_ZERO_MUTE    shadow_audioxmt1 |= 0x40;		/* Enable zero_mute (better S/N)*/    DSC_cmd(dsc_audioxmt1, shadow_audioxmt1);#endif}#endif /* end of #ifdef ECHO */void DSC_zero_mute(int on){#ifdef ECHO     if (vcx_echo == -1) #endif     {         if (on) {             shadow_audioxmt1 |= 0x40;         } else {             shadow_audioxmt1 &= 0xbf;         }         DSC_cmd(dsc_audioxmt1, shadow_audioxmt1);     }}/* * Fuction to set and/or clear AUX pins on 3205/3207/3209. * * Inputs: *	sel:	0 - for dsc_aux0  *		1 - for dsc_aux1 *		2 - for dsc_aux2 *	set:	0 - clear    according to mask *		1 - set      according to mask *		2 - tristate pads specified by mask *	mask:	mask to be used */void DSC_set_aux(sel, set, mask)int sel, set, mask;{    register psw_shadow, temp;    volatile char *ptr;    int data, ctl, *pdat, *pctl;    volatile unsigned int *ptrdelay = (unsigned int *) bank3safe;    asm volatile("movfrs psw,%0":  "=r" (psw_shadow) );     /* Non-cachable bank1 address (CS1) */    ptr = DSC_ADDRESS;    /* Decide which 3207 register to use (dsc_aux0 vs. dsc_aux1) */#ifdef IO3890    if (sel == 2) {	pdat = &shadow_eaux2_dat;	pctl = &shadow_eaux2_ctl;	data = dsc_aux2_data;	ctl  = dsc_aux2_ctl;    } else #endif     if (sel == 1) {	pdat = &shadow_eaux1_dat;	pctl = &shadow_eaux1_ctl;	data = dsc_aux1_data;	ctl  = dsc_aux1_ctl;    } else {	pdat = &shadow_eaux0_dat;	pctl = &shadow_eaux0_ctl;	data = dsc_aux0_data;	ctl  = dsc_aux0_ctl;    }    /* Disable interrupt so everything can happen together */    temp = 0x1fd5;    asm volatile("movtos %0,psw" :  :"r" (temp));     asm("nop");    asm("nop");    /* Set the PAD value first (keep a copy in shadow) */    *ptr = data;    (void) *ptrdelay;    /* When setting or tri-stating, OR in the mask */    if (set) *ptr = (*pdat |= mask);    else *ptr = (*pdat &= ~mask);        /* Set the enable bit (unless it is tri-state) */    (void) *ptrdelay;    *ptr = ctl;    (void) *ptrdelay;    /* When tri-stating, turn the bit off */    if (set == 2) *ptr = (*pctl &= ~mask);    else *ptr = (*pctl |= mask);    /* Restore PSD */    asm volatile("movtos %0,psw" :  :"r" (psw_shadow)); }/* * Set 3207 TV mode to PAL or NTSC. * * Input: *	mode:	TV_NTSC for NTSC *		TV_PAL  for PAL */void DSC_set_TV(mode)int mode;{    shadow_cchip_ctl &= ~1;		/* Disable DVE			*/    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);    DSC_cmd(dsc_dvectl1, (mode == TV_NTSC) ? 0x06 : 0x04);    shadow_cchip_ctl |= 1;		/* Enable DVE			*/    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);}#ifdef SVIDEO/* * Turn s-video on or off. * * Input: *	on:	1: turn it on *		0: turn it off */void DSC_s_video(on)int on;{    int dvectl3;    dvectl3 = DSC_cmd(dsc_dvectl3m, 0);	/* Get the current DVECTL3	*/    if (on) {        dvectl3 &= ~6;		/* Turn on S-Video		*/#ifdef IO3890        dvectl3 |= 0x80;        /* Enable Y and chroma output   */#endif    } else {#ifdef IO3890	dvectl3 |= 2;		/* Turn off Y DAC of S-video	*/        dvectl3 &= ~0x80;       /* Make C DAC outputs V signal	*/#else        dvectl3 |= 6;		/* Turn off S-Video		*/#endif    }    shadow_cchip_ctl &= ~1;		/* Disable DVE			*/    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);    DSC_cmd(dsc_dvectl3, dvectl3);    shadow_cchip_ctl |= 1;		/* Enable DVE			*/    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);}#endif/* * This routine is called to power down 3210. When 3210 is in power * down mode, it may run at 27MHz from 3207/9 (the old way) or run * from internal clock divider (newer chips.) * * This routine will ask 3207/9 to reset 3210; therefore, it will never * return. */#ifdef ES3207Avoid DSC_mute_on() {    volatile unsigned int *ptr = (unsigned int *) bank3safe;    int i, foo;    shadow_cchip_ctl |= 0x20;    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);    for (i=0; i<60000; i++)	/* wait for pin VREFM turn high */	foo = *ptr;		/* wait 360 ns; total wait 20ms */}#if 0void DSC_mute_off() {    volatile unsigned int *ptr = (unsigned int *) bank3safe;    int i, foo;    shadow_cchip_ctl &= 0xdf;    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);    for (i=0; i<60000; i++)	/* wait for pin VREFM turn high */	foo = *ptr;		/* wait 360 ns; total wait 20ms */}#endif#endif#ifdef PLAY20void DSC_powerdown(){    int clkctl = 0x70;			/* PLL, PCLK2X, divider 0, boot	*/    mvd[riface_irqmask] = 0;		/* Disable all interrupts	*/#ifdef ES3207A    DSC_mute_on();#endif    shadow_cchip_ctl &= ~1;		/* Disable DVE			*/    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);    DSC_VIDEO_OFF;			/* Power down video		*/    shadow_cchip_ctl = 0x38;		/* Audio mute, warm boot, power	*					 * saving, disable MIC/audio	*/    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);#ifdef IR_PHILIPS    clkctl |= ((IR_ctlbit & 1) << 1);	/* Record the last control bit.	*					 * DON'T change b2, 3881 can't	*					 * take it!!			*/#endif    DSC_cmd(dsc_clkctl, clkctl);    while (1);}

⌨️ 快捷键说明

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