dsc.c
来自「ESS3890+SL原代码(1*16内存)」· C语言 代码 · 共 1,030 行 · 第 1/2 页
C
1,030 行
#endif /* PLAY20 *//* * This routine powers up 3210. 3207/9 will reset 3210 so this routine * will never return. */void DSC_powerup(){ int clkctl = 0x71; /* PLL, PCLK2X, divider 1, boot */ mvd[riface_irqmask] = 0; /* Disable all interrupts */ shadow_cchip_ctl = 0x30; /* Audio mute, warm boot */ 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);}void DSC_set_audio_sampling_frequency(int freq){ typedef struct { unsigned char cnt0l; unsigned char cnt0h; unsigned char cnt1l; unsigned char cnt1h; unsigned char pllm; unsigned char plln; } DSC_AUDIO; DSC_AUDIO * ptr; unsigned char tmp_cnt0h;#ifdef IO3890 unsigned char tmp_plln;#endif if (mclk_used_for_servo) freq = 0; ptr = &(((DSC_AUDIO *) T_DSC_audiosettings)[freq]); tmp_cnt0h = ptr->cnt0h;#ifdef IO3890 tmp_plln = ptr->plln;#endif /* * 3207 only has digital PLL while 3883 has analog PLL * We will always use analog PLL for 3883 */#ifndef DSC_AUDIOCLK tmp_cnt0h &= ~0xf0; /* Select external MCLK */ DSC_cmd(dsc_audioacnt0h, tmp_cnt0h); return;#endif /* * 3890 case */#ifdef IO3890#ifdef FS384 tmp_plln |= 0x80; /* select 384 Fs */#endif DSC_cmd(dsc_audioacnt0h, tmp_cnt0h); DSC_cmd(dsc_audioapllm, ptr->pllm); DSC_cmd(dsc_audioaplln, tmp_plln); DSC_cmd(dsc_debug1, 0x00); DSC_cmd(dsc_debug1, 0x80); return;#endif /* IO3890 */ /* * 3883 case */#ifdef FS384 DSC_cmd(dsc_audioacnt0h, 0x76); /* 3207 outputs clock */ DSC_cmd(dsc_audioacnt0l, 0x20); /* 16.9344 MHz */ DSC_cmd(dsc_audioacnt1h, 0x0c); DSC_cmd(dsc_audioacnt1l, 0x5c);#else DSC_cmd(dsc_audioacnt0h, tmp_cnt0h); DSC_cmd(dsc_audioapllm, ptr->pllm); DSC_cmd(dsc_audioaplln, ptr->plln); DSC_cmd(dsc_audioacnt0l, ptr->cnt0l); DSC_cmd(dsc_audioacnt1h, ptr->cnt1h); DSC_cmd(dsc_audioacnt1l, ptr->cnt1l);#endif /* FS384 */}/* * Initialize 3207 */void DSC_init(){#ifdef ES3207A int i; volatile unsigned int *ptrdelay = (unsigned int *) bank3safe;#endif DSC_toggle(); /* Just in case */#ifdef IO3890 shadow_aux_mode &= ~0x01; /* set EAUX11 as GPIO */ DSC_cmd(dsc_aux_mode, shadow_aux_mode);#endif#if (!TCSERVO || !GDTSERVO || POWER_ON) /* If A/C is just turned on, we want to power down to standby mode */ if (DSC_status == DSC_STATUS_ACON) { /* init the game and vcd20 save memory */ int *ptr;#ifdef PLAY20 ptr = RISC_ptr_realtime; *ptr-- = 0; /* realtime */ *ptr-- = 0; /* resume info */ *ptr = 0; /* resume info */ /* If you want to boot up in power up state, define "IGNORE_POWERDOWN" * in makefile. Don't change to DSC_powerup() here!! */ DSC_powerdown(); #endif }#endif /* POWER_ON */ if (IS_POWER_DOWN) { /* In power-down mode. Turn off few parts of 3207 */#ifndef MCLK_FOR_SERVO DSC_cmd(dsc_audioacnt0h, 0x06); /* Disable MCLK output */#endif shadow_cchip_ctl |= DSC_CCHIP_CTL_IR_EN; /* Enable interrupt for 3881. */ DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl); DSC_cmd(dsc_clkctl, 0x30); /* PLL, PCLK2X, divider 0 */ DSC_VIDEO_OFF; } else { DSC_status = DSC_STATUS_RUNNING;/* With 8051, A/C on goes to * * run state, so fake it! */#ifdef ES3207A shadow_cchip_ctl = 0x30 | DSC_CCHIP_CTL_IR_EN; /* Warm and Audio mute. Enable * * interrupt for 3881 */#else shadow_cchip_ctl = 0x10 | DSC_CCHIP_CTL_IR_EN; /* Warm and Audio mute. Enable * * interrupt for 3881. */#endif DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl); DSC_cmd(dsc_dvectl4, 0x31); /* enable sync outputs */#ifdef SVIDEO#ifdef SVIDEO_SELECT if (S_VIDEO_ON) { DSC_VIDEO_ON; svideo_setting = 1; /* enable composite + s-video */ } else { DSC_COMPOSITE_ONLY; svideo_setting = 0; /* enable composite video dac only */ }#else DSC_VIDEO_ON; /* enable composite + s-video */#endif#else DSC_COMPOSITE_ONLY; /* enable composite video dac only */#endif /* SVIDEO */ DSC_cmd(dsc_clkctl, 0x39); /* enable dve, PLL, PCLK2X, PCLK* * Divider set to 1 (running) */ DSC_cmd(dsc_audioadc2, 0x00 | AUDIOADC2_RESET); /* Reset A2D to minimize noise */#ifdef ECHO /* Invert ATFS; output ACLK; MSB first; * down sampling mute zero (VA and later) */ shadow_audioxmt1 = 0x29|ZERO_MUTE_BIT;#else /* no echo */ /* Invert ATFS; external ACLK; MSB first (irrelevant) * mute zero (VA and later) */ shadow_audioxmt1 = 0x20|ZERO_MUTE_BIT;#endif /* end ifdef ECHO */ DSC_cmd(dsc_audioxmt1, shadow_audioxmt1);#if (!defined(DSC_AUDIOCLK) && !defined(AUDIOCLK) && defined(FS384) && defined(IO3890)) DSC_cmd(dsc_audiodbg, 0x03);#else DSC_cmd(dsc_audiodbg, 0x01);#endif#ifdef ES3207A /* When we are using 3207 DAC */ DSC_set_audio_sampling_frequency(DSC_44K); DSC_cmd(dsc_audiorcv1, 0x80 | AUDIORCV1_DITHER); /* Right adjusted & reset */#ifdef FS384 DSC_cmd(dsc_audiorcv2, 0x11); /* 24b cycle frame (384*FS) */#else DSC_cmd(dsc_audiorcv2, 0x10); /* 16b cycle frame (256*FS) */#endif DSC_cmd(dsc_audiorcv1, 0x90 | AUDIORCV1_DITHER); /* Enable (disable reset) */#ifndef ZERO_BUFFER shadow_cchip_ctl |= 0x1; /* Enable video DAC only */#else /* * When zero buffer is used, we'll not call DSC_reset_audio, * so we need to turn on audio DAC once and for all. */ shadow_cchip_ctl |= 0x3; /* Enable video+audio DAC */ for (i = 0; i < 10000; i++) (void) *ptrdelay;#endif /* ZERO_BUFFER */ DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);#else /* NOT ES3207A */ /* When using external audio DAC */#ifdef ECHO DSC_set_audio_sampling_frequency(DSC_44K);#else DSC_cmd(dsc_audioacnt0h, 0x06); /* Disable 3207's clock */#endif shadow_cchip_ctl |= 0x21; /* Enable the external DAC (i.e.* * disable the mute pin) */ DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);#endif /* ES3207A */ } /* * Initialize a 2 second watch dog timer. 3207 operates at 54MHz, * so 2 second is (n+1)*8/54, and n is 12.5. The initial clock * setting has to be (0x7f-0xd)|0x80 */ DSC_cmd(dsc_watchdog, 0xf2);}/* * Turn off 3207/9's TV encoder */void DSC_encoder_off(){ DSC_VIDEO_OFF;}#ifdef POWER_NOISE_MUTE/* * Turn on 3207/9's TV encoder */void DSC_encoder_on(){ DSC_VIDEO_ON;}#endifPRIVATE int la_trigger; /* For logic analyzer *//* * This routine will be called inside interrupt handler. With 3207, we'll * be reset by 3207; without 3207, we'll just jump to start up code. */void DSC_dead(trigger)int trigger;{ /* Sit here and wait for 3207 to reset us. */ while (1) la_trigger = trigger;}#ifdef DSC_TURN_OFF_DVEvoid DSC_turn_dve_off(void) { DSC_VIDEO_OFF;#ifndef ANTI_SHOCK /* Running at 1/4th of full speed */ mvd[riface_width] = 0x61; asm("nop"); asm("nop"); /* B0 0 WS, B1 32 WS, B2 1 WS, B3 1 WS */ mvd[riface_wait_state] = 0x1f781f;#else /* Running at 1/2th of full speed */ mvd[riface_width] = 0x41; asm("nop"); asm("nop"); /* B0 0 WS, B1 32 WS, B2 2 WS, B3 3 WS */ mvd[riface_wait_state] = 0x1e741f;#endif}void DSC_turn_dve_on(void) { DSC_VIDEO_ON; /* Running at full speed */ mvd[riface_width] = 0x1; asm("nop"); asm("nop"); /* B0 1 WS, B1 32 WS B2 4 WS, B3 7 WS */ mvd[riface_wait_state] = 0x1c6c1e;}#endif#ifdef DSC_IRQ/* * This routine updates dsc_aux_mode and dsc_irq_ctl registers. * * Inputs: * on: 0: turning off * 1: turning on * edge: 0: trigger on rising edge * 1: trigger on falling edge * setmode:0: Don't touch dsc_aux_mode and IRQOUT. They are right (only * used for change IR trigger edge for Philips IR.) * 1: Drive IRQOUT high and set dsc_aux_mode (normal case) * mask: interrupt mask; * falling:patter to enable triggering on falling edge */PRIVATE void DSC_init_irq_ctl(on, edge, setmode, mask, falling)int on, edge, setmode, mask, falling;{ int mode, ctl; mode = shadow_aux_mode; ctl = shadow_irq_ctl; /* Set irq_ctl register */ ctl &= ~mask; /* Clear the mask first */ if (on) { ctl |= mask; /* Enable the interrupt */ ctl &= ~falling; /* Assume trigger on rising edge*/ if (edge == DSC_FALLING_EDGE) ctl |= falling; } if (setmode) { /* Set aux_mode register */ mode &= ~2; /* Clear SQCK */#ifndef ESS3721 /* If S0S1 is enabled, then enable SQCK */ if (ctl & 2) mode |= 2;#endif /* If no interrupt mask is on, then disable interrupt output */ mode &= ~1;#ifndef IO3890 /* in ES3890, IRQ is internally connected */ if (ctl & 0xf) { mode |= 1; CLEAR_IRQOUT; /* Drive EAUX11 low */ CLEAR_IRXOR; /* EAUX11 is active high */ }#endif /* IO3890 */ /* * The only time setmode is not set is when changing the * IR triggering edge for Philips IR. In which case, there * is no need to change mode. */ shadow_aux_mode = mode; DSC_cmd(dsc_aux_mode, shadow_aux_mode); } /* * Need to protect because we may change IR's edge in IR handler. * Thus, it is possible that interrupt hits after shadow_irq_ctl * but before dsc_irq_ctl is really updated. * * riface_irqsuppress should be good enought because we do * riface_irqsuppress inside DSC_cmd; */ mvd[riface_irqsuppress] = 0; asm("nop"); shadow_irq_ctl = ctl; DSC_cmd(dsc_irq_ctl, shadow_irq_ctl);}/* * Turn ON or OFF IR handling by 3881 * Inputs: * on: 0: turn off * 1: turn on * edge: 0: rising * 1: falling * setmode:0: Don't set dsc_aux_mode (assume it is set right already) * 1: Set dsc_aux_mode as well as pull IRQOUT high (normal case) */void DSC_init_ir(on, edge, setmode)int on, edge, setmode;{ TRISTATE_IRIN; /* Allow IR to come in on EAUX15 */ DSC_init_irq_ctl(on, edge, setmode, 1, 0x10);}/* * Turn ON or OFF S0S1 handling by 3881 * Inputs: * on: 0: turn off * 1: turn on * edge: 0: rising * 1: falling * count: Number of SQCK to drive */void DSC_init_s0s1(on, edge, count){#if (defined DSC_ENABLE_S0S1 || defined CDG || defined CD_TEXT) if (on) { SET_SQCK; /* Initally drive SQCK high */ TRISTATE_SQSO; /* Ready to receive SQDT on EAUX9 */ TRISTATE_S0S1; /* Ready to receive S0S1 on EAUX14 */ DSC_cmd(dsc_subq_bcnt, count); /* Number of subQ clocks */ DSC_cmd(dsc_subq_ctl, 0); /* Set edge etc first. */ } DSC_init_irq_ctl(on, edge, 1, 2, 0x20);#endif}#ifdef USE_SERVO_INTvoid DSC_init_servoint(on, edge){ TRISTATE_SERVO_INT; DSC_init_irq_ctl(on, edge, 1, 2, 0x20);}#endif#ifdef DSC_ENABLE_16550/* * Turn ON or OFF "16550" handling by 3881 * Inputs: * on: 0: turn off * 1: turn on * edge: 0: rising * 1: falling */void DSC_init_16550(on, edge){ TRISTATE_16550; DSC_init_irq_ctl(on, edge, 1, 4, 0x40);}#endif#ifdef DSC_ENABLE_C2PO/* * Turn ON or OFF C2PO handling by 3881 * Inputs: * on: 0: turn off * 1: turn on * edge: 0: rising * 1: falling */void DSC_init_c2po(on, edge){ TRISTATE_C2PO; DSC_init_irq_ctl(on, edge, 1, 8, 0x80);}#endif#if (defined CDG || defined CD_TEXT)void DSC_init_subcode(on, edge){ if (on) {#ifndef NO_SERIAL shadow_aux_mode |= 0x4;#endif#ifdef EXCK_REVERSED CLEAR_EXCK;#else SET_EXCK; /*Initially drive EXCK high*/#endif TRISTATE_SBSO; /*Close serial port1 firstly, it will trigger in WFCK isr*/#ifndef NO_SERIAL DSC_cmd(dsc_vfd_ctl, 0);#endif } /* input signal..always tristate! even when disabling interrupt */ TRISTATE_WFCK; /* Ready to receive interrupt */ DSC_init_irq_ctl(on, edge, 1, (IRQ_CTL_WFCK>>4), IRQ_CTL_WFCK);}#endif#endif /* DSC_IRQ */#else/* * This routine will be called inside interrupt handler. With 3207, we'll * be reset by 3207; without 3207, we'll just jump to start up code. */void DSC_dead(trigger)int trigger;{ /* * Jump to startup code. Startup code is at 0xcffff80, but code * uses DWORD address, which makes it 0x33fffe0. */ asm("addi r0,#0x33f,r22"); asm("lsl r22,r22,#16"); asm("addi r22,#0xffe0,r22"); asm("jspci r22,#0,r0"); asm("nop"); asm("nop");}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?