📄 play_capture_tw.c
字号:
if (argi + 1 >= argc) goto SKIP; if (argv[argi + 1][0] == '-') goto SKIP; SCANPARAM(options->i2c_video_dev, "please specify a video i2c device address", 1); options->i2c_video_dev >>= 1; if (err == RM_ERROR) goto SKIP; if (argi + 1 >= argc) goto SKIP; if (argv[argi + 1][0] == '-') goto SKIP; SCANPARAM(options->i2c_video_delay, "please specify a delay value", 1); options->i2c_audio1_delay = options->i2c_video_delay; options->i2c_audio2_delay = options->i2c_video_delay; } else if (! strcmp(&(argv[argi][1]), "update")) { options->update = TRUE; } else if (! strcmp(&(argv[argi][1]), "gpiofid")) { options->use_gpio_fid = TRUE; } else if (! strcmp(&(argv[argi][1]), "fidinv")) { options->invert_fid = TRUE; } else if (! strcmp(&(argv[argi][1]), "eq")) { SCANPARAM(options->cable_eq, "please specify a cable length", 1); options->cable_eq &= 0x0F; } else if (! strcmp(&(argv[argi][1]), "fv")) { options->follow_vfreq = TRUE; } else if (! strcmp(&(argv[argi][1]), "v")) { if (options->verbouse) options->intr_debug = TRUE; options->verbouse = TRUE; } else if (! strcmp(&(argv[argi][1]), "bg")) { options->green_bg = TRUE; } else { err = RM_PENDING; } }SKIP: if (err == RM_OK) *index = argi + 1; return err;}static RMstatus init_capture_ADV7402( struct RUA *pInstance, struct capture_cmdline *capture_opt, struct local_cmdline *local_opt, RMuint8 dev, RMuint8 delay){ // ADV7402 setup RMuint8 i2c_data_cvbs[][2] = { // CVBS in {0x00, 0x0F}, // PAL/NTSC auto detect, CVBS in {0x03, 0x0C}, // OF_SEL: 8 bit 4:2:2, enabled {0x05, 0x00}, // CVBS in {0x15, 0x41}, // dig. clamp time const. {0x17, 0x41}, // {0x39, 0x40}, // PAL Comb {0x3A, 0x16}, // power down ADC 1&2 {0x3B, 0x80}, // ext. bias res. {0x4D, 0xEF}, // enable CTI {0x69, 0x01}, // SDM for CVBS on AIN11 {0xCD, 0x00}, // {0xCE, 0x01}, // {0xDB, 0xBB}, // // setup decoder // {0x0E, 0x80}, // // {0xB4, 0x13}, // // {0xB5, 0x03}, // // {0xD0, 0x4A}, // // {0xDC, 0xEF}, // // {0x0E, 0x00}, // }; RMuint8 i2c_data_yuv[][2] = { // YUV in {0x00, 0x09}, // PAL/NTSC auto detect, YUV in {0x05, 0x01}, // Component in {0x15, 0x41}, // dig. clamp time const. {0x27, 0xE1}, // {0x3B, 0x80}, // ext. bias res. {0x4D, 0xEF}, // enable CTI {0x51, 0x24}, // {0xC3, 0x46}, // route Ain6 to ADC0, Ain4 to ADC1 {0xC4, 0xF5}, // route Ain5 to ADC2 {0xCD, 0x00}, // {0xCE, 0x01}, // {0xDB, 0xBB}, // // setup decoder {0x0E, 0x80}, // {0xB5, 0x03}, // {0xD0, 0x44}, // {0xDC, 0xEF}, // {0x0E, 0x00}, // }; RMuint8 i2c_data_vga[][2] = { // VGA: {0x05, 0x02}, // VGA RGB in {0x06, 0x08}, // 640x480@60Hz {0x3A, 0x10}, // set latch clock settings to 001b {0x3B, 0x80}, // External Bias Enable {0x3C, 0x5C}, // PLL_QPUMP to 011b // RGB->YUV CSC {0x52, 0x00}, {0x53, 0x00}, {0x54, 0x07}, {0x55, 0x0C}, {0x56, 0x94}, {0x57, 0x89}, {0x58, 0x48}, {0x59, 0x08}, {0x5A, 0x00}, {0x5B, 0x20}, {0x5C, 0x03}, {0x5D, 0xA9}, {0x5E, 0x1A}, {0x5F, 0xB8}, {0x60, 0x08}, {0x61, 0x00}, {0x62, 0x7A}, {0x63, 0xE1}, {0x64, 0x00}, {0x65, 0x19}, {0x66, 0x48}, // 8 bit 4:2:2 output {0x67, 0x03}, // DPP decimation 4:2:2 oversampled // {0x67, 0x01}, // DPP decimation 4:2:2 {0x68, 0x00}, // {0x6A, 0x80}, // double output clock {0x6B, 0x83}, // 8/16 bit 4:2:2 {0x73, 0x90}, // manual gain mode {0x74, 0xB4}, // gain // 8 bit prec., 64 Y offset, 512 Cb and Cr offset {0x77, 0x84}, {0x78, 0x08}, {0x79, 0x02}, {0x7A, 0x00}, {0xB3, 0xFE}, // STDI & Free Run tweek {0xF4, 0x3F}, // Max Drive Strength {0xC9, 0x0C}, // Enable DDR Mode // {0x0E, 0x80}, // Enable Hidden Space // {0x58, 0xED}, // Change Xtal power to PVDD // {0x0E, 0x00}, // Disable Hidden Space }; switch (local_opt->i2c_port) { case cap_CVBS1: case cap_CVBS2: case cap_SVideo1: case cap_SVideo2: return init_i2c(pInstance, delay, dev, i2c_data_cvbs, sizeof(i2c_data_cvbs) / sizeof (RMuint8) / 2); case cap_VGA: return init_i2c(pInstance, delay, dev, i2c_data_vga, sizeof(i2c_data_vga) / sizeof (RMuint8) / 2); case cap_Component1: case cap_Component2: return init_i2c(pInstance, delay, dev, i2c_data_yuv, sizeof(i2c_data_yuv) / sizeof (RMuint8) / 2); default: return RM_ERROR; } return RM_OK;}/* calculates nominal increment with 32 bit integer arithmetic *//* returns (f_in / f_out * 2 ^ frac_bits */static RMuint32 nominal_increment(RMuint32 f_in, RMuint32 f_out, RMuint32 frac_bits) { RMuint32 div; RMint32 shift; /* sanity check */ if (!f_out) { RMDBGLOG((ENABLE, "Error: clean divider output frequency not set!\n")); return 0; } /* align denominator to enumerator */ div = 0; shift = 0; while ((f_out < f_in) && ((f_out & 0x80000000) == 0)) { f_out <<= 1; shift++; } /* calculate integer part of division */ while (1) { if (f_in >= f_out) { f_in -= f_out; div |= 1; } if (! shift) break; f_out >>= 1; div <<= 1; shift--; } div <<= 1; /* calculate first frac_bits bits of fractional part */ while (1) { if (f_in & 0x80000000) { if ( ((f_in == (f_out >> 1)) && (!(f_out & 1))) || (f_in > (f_out >> 1))) { f_in -= (f_out >> 1); div |= 1; } f_in <<= 1; if (f_out & 1) f_in -= 1; } else { f_in <<= 1; if (f_in >= f_out) { f_in -= f_out; div |= 1; } } if (shift <= (((RMint32)frac_bits - 1) * -1)) break; if (div & 0x80000000) RMDBGLOG((ENABLE, "Overflow!\n")); div <<= 1; shift--; } return div;}static RMstatus init_capture_SAA7119_amclk( struct RUA *pInstance, struct capture_cmdline *capture_opt, struct local_cmdline *local_opt, RMuint8 dev, RMuint8 delay, RMuint32 sample_clk, RMuint32 xtal_clk, RMbool use_cg2){ RMstatus err; RMuint32 mclk, acpf = 0, acni = 0; struct EMhwlibTVFormatDigital fmt; RMuint32 vfreq_n, vfreq_m; // Philips SAA 7119 audio PLL setup // mclk = sample_clk * 256 // sclk = sample_clk * 64 // lrclk = sample_clk RMuint8 i2c_data[][2] = { {0x30, 0x00}, // 0 [7:0] acfp = mclk / v-freq {0x31, 0xc0}, // 1 [15:8] {0x32, 0x03}, // 2 [17:16] {0x34, 0xce}, // 3 [7:0] acni = mclk * 2^23 / xtal_clk {0x35, 0xfb}, // 4 [15:8] {0x36, 0x30}, // 5 [21:16] {0x38, 0x01}, // 6 sdiv = (mclk / (2 * sclk)) - 1; {0x39, 0x20}, // 7 lrdiv = sclk / lrclk / 2 {0x3a, 0x00}, // 8 80:use CG2, 08:freerunning/00:fieldlocked {0x3b, 0x3f}, // 3b-3f recommended values {0x3c, 0xd1}, {0x3d, 0x31}, {0x3e, 0x03}, }; RMuint8 i2c_data_ext[][2] = { {0xE0, 0x00}, // 0 [7:0] splpl = clk_lfco / h-freq * 2 {0xE1, 0x08}, // 1 [3:0]sppi=0, [1:0]spmod=2 [9:8]splpl {0xE2, 0x03}, // 2 [7:0] spninc = 2^17 * clk_lfco / xtal_clk {0xE3, 0xce}, // 3 [15:8]spninc {0xE4, 0x88}, // 4 [3:0]spthrl=8, [3:0]spthrm=8 {0xE5, 0x00}, // 5 spbypns=0, [6:0]cg2fbd {0xE6, 0xd0}, // 6 cg2divres=1, cg2en=1, sphsel=0, [2:0]cg2ckdl=4, [1:0]cg2od {0xE7, 0x31}, // 7 [3:0]cg2r=3, [3:0]cg2i=1 {0xE8, 0x03}, // 8 [4:0]cg2p=3 }; mclk = sample_clk * 256; // get current capture video format err = RUAGetProperty(pInstance, capture_opt->InputModuleID, RMGenericPropertyID_TVFormat, &fmt, sizeof(fmt)); if (RMFAILED(err) || (fmt.HTotalSize == 0) || (fmt.VTotalSize == 0)) { fprintf(stderr, "Failed to get valid TVFormat from input, assuming 59.94 Hz video\n"); vfreq_m = 1001; vfreq_n = 60000; } else { if ((fmt.PixelClock == 74175824) || (fmt.PixelClock == 148351648)) vfreq_m = 1001; else vfreq_m = ((fmt.HTotalSize * fmt.VTotalSize) % 1001 == 0) ? 1001 : 1000; vfreq_n = ((RMuint64)fmt.PixelClock * (RMuint64)vfreq_m * (fmt.TopFieldHeight ? 2 : 1)) / fmt.HTotalSize / fmt.VTotalSize; } if (use_cg2) { // Audio PLL --> CG2 PLL --> MClk,SClk,LRClk RMuint32 LFCO_freq, k; RMuint32 splpl, spninc, cg2fbd, cg2od; k = (mclk + (3375000 / 2)) / 3375000; if (k < 4) k = 4; LFCO_freq = mclk / k; acpf = (RMuint32)(((RMuint64)vfreq_m * (RMuint64)LFCO_freq * 2) / vfreq_n); acni = nominal_increment(LFCO_freq, xtal_clk, 24); // mclk = LFCO_freq * 2 * (cg2fbd + 1) / (cg2od + 1) / 4, cg2fbd=31..92(94?), cg2od=0..3 for (cg2od = 0; cg2od < 4; cg2od++) { cg2fbd = k * 4 * (cg2od + 1) / 2 - 1; // LFCO_freq * 2 * mclk / (cg2od + 1) / 4 - 1; if ((cg2fbd >= 31) && (cg2fbd <= 94)) { // Check PLL internal frequency range, for square pixel mode only //RMuint32 clk_int = LFCO_freq * 2 * (cg2fbd + 1); //if ((clk_int >= 275000000) && (clk_int <= 550000000)) break; break; } } if (cg2od >= 4) { fprintf(stderr, "Can not use CG2, fall back to audio PLL\n"); use_cg2 = FALSE; } else { if (fmt.PixelClock) { splpl = (RMuint32)(((RMuint64)LFCO_freq * (RMuint64)fmt.HTotalSize * 2) / fmt.PixelClock); } else { splpl = 0; } spninc = nominal_increment(LFCO_freq, xtal_clk, 17); i2c_data_ext[0][1] = RMunshiftBits(splpl, 8, 0); i2c_data_ext[1][1] |= RMunshiftBits(splpl, 2, 8); i2c_data_ext[2][1] = RMunshiftBits(spninc, 8, 0); i2c_data_ext[3][1] = RMunshiftBits(spninc, 8, 8); i2c_data_ext[5][1] |= RMunshiftBits(cg2fbd, 7, 0); i2c_data_ext[6][1] |= RMunshiftBits(cg2od, 2, 0); err = init_i2c(pInstance, delay, dev + 4, i2c_data_ext, sizeof(i2c_data_ext) / sizeof (RMuint8) / 2); if (RMFAILED(err)) return err; i2c_data[8][1] = 0x80; // enable CG2 } } if (! use_cg2) { // Audio PLL --> MClk,SClk,LRClk acpf = (RMuint32)((((RMuint64)vfreq_m * (RMuint64)mclk) + (vfreq_n / 2)) / vfreq_n); acni = nominal_increment(mclk, xtal_clk, 23); } i2c_data[0][1] = RMunshiftBits(acpf, 8, 0); i2c_data[1][1] = RMunshiftBits(acpf, 8, 8); i2c_data[2][1] = RMunshiftBits(acpf, 2, 16); i2c_data[3][1] = RMunshiftBits(acni, 8, 0); i2c_data[4][1] = RMunshiftBits(acni, 8, 8); i2c_data[5][1] = RMunshiftBits(acni, 6, 16); err = init_i2c(pInstance, delay, dev, i2c_data, sizeof(i2c_data) / sizeof (RMuint8) / 2); if (RMFAILED(err)) return err; return err;}static RMstatus init_capture_SiI9031_amclk( struct RUA *pInstance, RMuint8 dev, RMuint8 delay, RMbool enable){ RMstatus err; RMuint8 i2c_data_ext[][2] = { {0x00, 0x85}, // init ACR in auto mode, no overrides {0x02, 0x52}, // MClk=256*fs {0x13, 0x03}, // recommended WINDIV value {0x14, 0x00}, // recommended LKTHRESH value {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x10}, // enable fs filter {0x18, 0x0C}, // enable MClk loop back {0x26, 0xC0}, // I2S: 32 bit frames, align 1 (philips format) {0x28, 0xE4}, // default FIFO mapping {0x2E, 0x00}, // no swap {0x32, 0x00}, // no mute }; err = init_i2c(pInstance, delay, dev + 4, i2c_data_ext, sizeof(i2c_data_ext) / sizeof (RMuint8) / 2); if (RMFAILED(err)) { fprintf(stderr, "Failed to init SiI9031!\n"); return err; } if (enable) { err = write_i2c(pInstance, delay, dev + 4, 0x27, 0x19); // Enable I2S0 out and MClk, send PCM only on I2S err = write_i2c(pInstance, delay, dev + 4, 0x29, 0x3D); // Enable I2S and SPDIF signals and HW-mute } else { err = write_i2c(pInstance, delay, dev + 4, 0x27, 0x01); // Disable I2S0 out and MClk, send PCM only on I2S err = write_i2c(pInstance, delay, dev + 4, 0x29, 0x38); // Disable I2S and SPDIF signals }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -