⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devtv.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
	uchar *abuf;	int s, d;	if (bt878 == nil || tv->amux == nil)		error("#V: Card does not support audio");	selector = 0;	if (!strcmp(input, "tv"))		selector = asel_tv;	else 	if (!strcmp(input, "radio"))		selector = asel_radio;	else 	if (!strcmp(input, "mic"))		selector = asel_mic;	else 	if (!strcmp(input, "smxc"))		selector = asel_smxc;	else		error("#V: Invalid input");	if (nasz > 0xfff)		error("#V: Audio block size too big (max 0xfff)");	abuf = (uchar *)malloc(nab * nasz * sizeof(uchar));	assert(abuf);	arisc = riscaudio(PADDR(abuf), nab, nasz);	ilock(tv);	if (tv->arisc) {		iunlock(tv);		free(abuf);		free(arisc);		error(Einuse);	}	tv->arisc = arisc;		tv->abuf = abuf;	tv->nablocks = nab;	tv->absize = nasz;	bt878->riscstrtadd = PADDR(tv->arisc);	bt878->packetlen = (nab << 16) | nasz;	bt878->intmask = 				intstat_scerr | intstat_ocerr | intstat_risci | 				intstat_pabort | intstat_riperr | intstat_pperr | 				intstat_fdsr | intstat_ftrgt | intstat_fbus;	/* Assume analog, 16bpp */	for (s = 0; s < 16; s++)		if (rate << s > Hwbase_ad * 4 / 15)			break;	for (d = 15; d >= 4; d--)		if (rate << s < Hwbase_ad * 4 / d)			break;	print("astart: sampleshift %d, decimation %d\n", s, d);	tv->narblocks = 0;	bt878->gpiodmactl = gpiodmactl_fifoenable | 			gpiodmactl_riscenable | gpiodmactl_acapenable |			gpiodmactl_daes2 | /* gpiodmactl_apwrdn | */			gpiodmactl_daiomda | (d << 8) | (9 << 28) | (selector << 24);	print("dmactl %.8ulX\n", bt878->gpiodmactl);	iunlock(tv);}static voidastop(Tv *tv){	Bt848 *bt878 = tv->bt878;	ilock(tv);	if (tv->aref.ref > 0) {		iunlock(tv);		error(Einuse);	}	if (tv->abuf) {		bt878->gpiodmactl &= ~gpiodmactl_riscenable;		bt878->gpiodmactl &= ~gpiodmactl_fifoenable;		free(tv->abuf);		tv->abuf = nil;		free(tv->arisc);		tv->arisc = nil;	}	iunlock(tv);}static voidvgastart(Tv *tv, ulong pa, int stride){	Frame *frame;	frame = (Frame *)malloc(sizeof(Frame));	assert(frame);	if (waserror()) {		free(frame);		nexterror();	}	frame->fbase = nil;	frame->fstart = riscpacked(pa, 0, ntsc_hactive * getbitspp(tv) / 8, 						   ntsc_vactive, stride * getbitspp(tv) / 8, 						   &frame->fjmp);	*frame->fjmp = PADDR(frame->fstart);	vactivate(tv, frame, 1);}static voidvstop(Tv *tv){	Bt848 *bt848 = tv->bt848;	ilock(tv);	if (tv->fref.ref > 0) {		iunlock(tv);		error(Einuse);	}	if (tv->frames) {		int i;		bt848->gpiodmactl &= ~gpiodmactl_riscenable;		bt848->gpiodmactl &= ~gpiodmactl_fifoenable;		bt848->capctl &= ~(capctl_captureodd|capctl_captureeven);		for (i = 0; i != tv->nframes; i++)			if (tv->frames[i].fbase)				free(tv->frames[i].fbase);		free(tv->frames);		tv->frames = nil;	}	iunlock(tv);}static longhrcfreq[] = {	/* HRC CATV frequencies */	    0,  7200,  5400,  6000,  6600,  7800,  8400, 17400,	18000, 18600, 19200, 19800, 20400, 21000, 12000, 12600,	13200, 13800, 14400, 15000, 15600, 16200, 16800, 21600,	22200, 22800, 23400, 24000, 24600, 25200, 25800, 26400,	27000, 27600, 28200, 28800, 29400, 30000, 30600, 31200,	31800, 32400, 33000, 33600, 34200, 34800, 35400, 36000,	36600, 37200, 37800, 38400, 39000, 39600, 40200, 40800,	41400, 42000, 42600, 43200, 43800, 44400, 45000, 45600,	46200, 46800, 47400, 48000, 48600, 49200, 49800, 50400,	51000, 51600, 52200, 52800, 53400, 54000, 54600, 55200,	55800, 56400, 57000, 57600, 58200, 58800, 59400, 60000,	60600, 61200, 61800, 62400, 63000, 63600, 64200,  9000,	 9600, 10200, 10800, 11400, 64800, 65400, 66000, 66600,	67200, 67800, 68400, 69000, 69600, 70200, 70800, 71400,	72000, 72600, 73200, 73800, 74400, 75000, 75600, 76200,	76800, 77400, 78000, 78600, 79200, 79800,};static voidfrequency(Tv *tv, int channel, int finetune){	Tuner *tuner = tv->tuner;	long freq;	ushort div;	uchar cfg;	if (channel < 0 || channel > nelem(hrcfreq))		error(Ebadarg);	freq = (hrcfreq[channel] * Freqmultiplier) / 100;	if (freq < tuner->freq_vhfh)		cfg = tuner->VHF_L;	else if (freq < tuner->freq_uhf)		cfg =  tuner->VHF_H;	else		cfg = tuner->UHF;	div = (freq + tuner->offs + finetune) & 0x7fff;		if (!i2cwrite(tv, tv->i2ctuneraddr, (div >> 8) & 0x7f, div, 1))		error(Eio);		if (!i2cwrite(tv, tv->i2ctuneraddr, tuner->cfg, cfg, 1))		error(Eio);	tv->channel = channel;	if (tv->msp)		msptune(tv);}static struct {	char *cmode;	ulong realmode;	ulong cbits;} colormodes[] = {{	"RGB16",		colorfmt_rgb16,		colorfmt_rgb16,		},{	"YCbCr422",	colorfmt_YCbCr422,	colorfmt_YCbCr422,	},{	"YCbCr411",	colorfmt_YCbCr411,	colorfmt_YCbCr422,	},};static voidcolormode(Tv *tv, char *colormode){	Bt848 *bt848 = tv->bt848;	int i;	for (i = 0; i != nelem(colormodes); i++)		if (!strcmp(colormodes[i].cmode, colormode))			break;	if (i == nelem(colormodes))		error(Ebadarg);	tv->cfmt = colormodes[i].realmode;	bt848->colorfmt = colormodes[i].cbits;}static intgetbitspp(Tv *tv){	switch (tv->cfmt) {	case colorfmt_rgb16:	case colorfmt_YCbCr422:		return 16;	case colorfmt_YCbCr411:		return 12;	default:		error("getbitspp: Unsupport color format\n");	}		return -1;}static char *getcolormode(ulong cmode){	switch (cmode) {	case colorfmt_rgb16:		return "RGB16";	case colorfmt_YCbCr411:		return "YCbCr411";	case colorfmt_YCbCr422:		return (cmode == colorfmt_YCbCr422)? "YCbCr422": "YCbCr411";	default:		error("getcolormode: Unsupport color format\n");	}		return nil;}static voidi2c_set(Tv *tv, int scl, int sda){	Bt848 *bt848 = tv->bt848;	ulong d;	bt848->i2c = (scl << 1) | sda;	d = bt848->i2c;	USED(d);	microdelay(i2c_delay);}static uchari2c_getsda(Tv *tv){	Bt848 *bt848 = tv->bt848;	return bt848->i2c & i2c_sda;}static voidi2c_start(Tv *tv){	i2c_set(tv, 0, 1);	i2c_set(tv, 1, 1);	i2c_set(tv, 1, 0);	i2c_set(tv, 0, 0);}static voidi2c_stop(Tv *tv){	i2c_set(tv, 0, 0);	i2c_set(tv, 1, 0);	i2c_set(tv, 1, 1);}static voidi2c_bit(Tv *tv, int sda){	i2c_set(tv, 0, sda);	i2c_set(tv, 1, sda);	i2c_set(tv, 0, sda);}static inti2c_getack(Tv *tv){	int ack;	i2c_set(tv, 0, 1);	i2c_set(tv, 1, 1);	ack = i2c_getsda(tv);	i2c_set(tv, 0, 1);	return ack;}static inti2c_wr8(Tv *tv, uchar d, int wait){	int i, ack;	i2c_set(tv, 0, 0);	for (i = 0; i != 8; i++) {		i2c_bit(tv, (d & 0x80)? 1: 0);		d <<= 1;	}	if (wait)		microdelay(wait);	ack = i2c_getack(tv);	return ack == 0;}static uchari2c_rd8(Tv *tv, int lastbyte){	int i;	uchar d;	d = 0;	i2c_set(tv, 0, 1);	for (i = 0; i != 8; i++) {		i2c_set(tv, 1, 1);		d <<= 1;		if (i2c_getsda(tv))			d |= 1;		i2c_set(tv, 0, 1);	}		i2c_bit(tv, lastbyte? 1: 0);	return d;}static intmspsend(Tv *tv, uchar *cmd, int ncmd){	int i, j, delay;	for (i = 0; i != 3; i++) {		delay = 2000;		i2c_start(tv);		for (j = 0; j != ncmd; j++) {			if (!i2c_wr8(tv, cmd[j], delay))				break;			delay = 0;		}		i2c_stop(tv);		if (j == ncmd)			return 1;		microdelay(10000);		print("mspsend: retrying\n");	}	return 0;}static intmspwrite(Tv *tv, uchar sub, ushort reg, ushort v){	uchar b[6];	b[0] = i2c_msp3400;	b[1] = sub;	b[2] = reg >> 8;	b[3] = reg;	b[4] = v >> 8;	b[5] = v;	return mspsend(tv, b, sizeof b);}static intmspread(Tv *tv, uchar sub, ushort reg, ushort *data){	uchar b[4];	int i;	b[0] = i2c_msp3400;	b[1] = sub;	b[2] = reg >> 8;	b[3] = reg;	for (i = 0; i != 3; i++) {		i2c_start(tv);		if (!i2c_wr8(tv, b[0], 2000) ||			!i2c_wr8(tv, b[1] | 1, 0) || 			!i2c_wr8(tv, b[2], 0) || 			!i2c_wr8(tv, b[3], 0)) {			i2c_stop(tv);			microdelay(10000);			print("retrying\n");			continue;		}		i2c_start(tv);		if (!i2c_wr8(tv, b[0] | 1, 2000)) {			i2c_stop(tv);			continue;		}				*data = i2c_rd8(tv, 0) << 8;		*data |= i2c_rd8(tv, 1);		i2c_stop(tv);		return 1;	}	return 0;}static uchar mspt_reset[] = { i2c_msp3400, 0, 0x80, 0 };static uchar mspt_on[] = { i2c_msp3400, 0, 0, 0 };static intmspreset(Tv *tv){	ushort v, p;	Bt848 *bt848 = tv->bt848;	ulong b;	b = 1 << 5;	gpioenable(tv, ~b, b);	gpiowrite(tv, ~b, 0);	microdelay(2500);	gpiowrite(tv, ~b, b);	bt848->i2c = 0x80;	microdelay(2000);	mspsend(tv, mspt_reset, sizeof mspt_reset);	microdelay(2000);	if (!mspsend(tv, mspt_on, sizeof mspt_on)) {		print("#V: Cannot find MSP34x5G on the I2C bus (on)\n");		return 0;	}	microdelay(2000);	if (!mspread(tv, msp_bbp, 0x001e, &v)) {		print("#V: Cannot read MSP34xG5 chip version\n");		return 0;	}	if (!mspread(tv, msp_bbp, 0x001f, &p)) {		print("#V: Cannot read MSP34xG5 product code\n");		return 0;	}	print("#V: MSP34%dg ROM %.d, %d.%d\n", 		(uchar)(p >> 8), (uchar)p, (uchar)(v >> 8), (uchar)v);	tv->msp = 1;	return 1;}static voidmspvolume(Tv *tv, int mute, int l, int r){	short v, d;	ushort b;	if (mute) {		v = 0;		b = 0;	}	else {		tv->aleft = l;		tv->aright = r;		d = v = max(l, r);		if (d == 0)			d++;		b = ((r - l) * 0x7f) / d;	}	mspwrite(tv, msp_bbp, 0, v << 8);	mspwrite(tv, msp_bbp, 7, v? 0x4000: 0);	mspwrite(tv, msp_bbp, 1, b << 8);	}static char *mspaformat(int f){	switch (f) {	case 0:		return "unknown";	case 2:	case 0x20:	case 0x30:		return "M-BTSC";	case 3:		return "B/G-FM";	case 4:	case 9:	case 0xB:		return "L-AM/NICAM D/Kn";	case 8:		return "B/G-NICAM";	case 0xA:		return "I";	case 0x40:		return "FM-Radio";	}	return "unknown format";}	static voidmsptune(Tv *tv){	ushort d, s, nicam;	int i;	mspvolume(tv, 1, 0, 0);	if (!mspwrite(tv, msp_dem, 0x0030, 0x2033))		error("#V: Cannot set MODUS register");	if (!mspwrite(tv, msp_bbp, 0x0008, 0x0320))		error("#V: Cannot set loadspeaker input");	if (!mspwrite(tv, msp_dem, 0x0040, 0x0001))		error("#V: Cannot set I2S clock freq");	if (!mspwrite(tv, msp_bbp, 0x000d, 0x1900))		error("#V: Cannot set SCART prescale");	if (!mspwrite(tv, msp_bbp, 0x000e, 0x2403))		error("#V: Cannot set FM/AM prescale");	if (!mspwrite(tv, msp_bbp, 0x0010, 0x5a00))		error("#V: Cannot set NICAM prescale");	if (!mspwrite(tv, msp_dem, 0x0020, 0x0001))		error("#V: Cannot start auto detect");	for (d = (ushort)-1, i = 0; i != 10; i++) {		if (!mspread(tv, msp_dem, 0x007e, &d))			error("#V: Cannot get autodetect info MSP34xG5");		if (d == 0 || d < 0x800)			break;		delay(50);	}	if (!mspread(tv, msp_dem, 0x0200, &s))		error("#V: Cannot get status info MSP34xG5");	mspvolume(tv, 0, tv->aleft, tv->aright);	nicam = ((s >> 4) & 2) | ((s >> 9) & 1);	snprint(tv->ainfo, sizeof tv->ainfo, "%s %s %s",			mspaformat(d), (s & (1 << 6))? "stereo": "mono",			nicamstate[nicam]);}static voidi2cscan(Tv *tv){	int i, ack;	for (i = 0; i < 0x100; i += 2) {		i2c_start(tv);		ack = i2c_wr8(tv, i, 0);		i2c_stop(tv);		if (ack) {			print("i2c device @%.2uX\n", i);		}	}	for (i = 0xf0; i != 0xff; i++) {		i2c_start(tv);		ack = i2c_wr8(tv, i, 0);		i2c_stop(tv);		if (ack)			print("i2c device may be at @%.2uX\n", i);	}}static voidgpioenable(Tv *tv, ulong mask, ulong data){	Bt848 *bt848 = tv->bt848;	bt848->gpioouten = (bt848->gpioouten & mask) | data;}static voidgpiowrite(Tv *tv, ulong mask, ulong data){	Bt848 *bt848 = tv->bt848;	bt848->gpiodata[0] = (bt848->gpiodata[0] & mask) | data;}static voidalteraoutput(Tv *tv){	if (tv->gpiostate == Gpiooutput)		return;	gpioenable(tv, ~0xffffff, 0x56ffff);	microdelay(10);	tv->gpiostate = Gpiooutput;}static voidalterainput(Tv *tv){	if (tv->gpiostate == Gpioinput)		return;	gpioenable(tv, ~0xffffff, 0x570000);	microdelay(10);	tv->gpiostate = Gpioinput;}static voidalterareg(Tv *tv, ulong reg){	if (tv->alterareg == reg)		return;	gpiowrite(tv, ~0x56ffff, (reg & 0x54ffff) | tv->alteraclock);	microdelay(10);	tv->alterareg = reg;}static voidalterawrite(Tv *tv, ulong reg, ushort data){	alteraoutput(tv);	alterareg(tv, reg);	tv->alteraclock ^= 0x20000;	gpiowrite(tv, ~0x56ffff, (reg & 0x540000) | data | tv->alteraclock);	microdelay(10);}static voidalteraread(Tv *tv, int reg, ushort *data){	Bt848 *bt848 = tv->bt848;	if (tv->alterareg != reg) {		alteraoutput(tv);		alterareg(tv, reg);	}	else {		gpioenable(tv, ~0xffffff, 0x560000);		microdelay(10);	}	alterainput(tv);	gpiowrite(tv, ~0x570000, (reg & 0x560000) | tv->alteraclock);	microdelay(10);	*data = (ushort)bt848->gpiodata[0];	microdelay(10);}static voidkfirloadu(Tv *tv, uchar *u, int ulen){	Bt848 *bt848 = tv->bt848;	int i, j;	ilock(&tv->kfirlock);	bt848->gpioouten &= 0xff000000;	bt848->gpioouten |= gpio_altera_data |		gpio_altera_clock | gpio_altera_nconfig;	bt848->gpiodata[0] &= 0xff000000;	microdelay(10);	bt848->gpiodata[0] |= gpio_altera_nconfig;	microdelay(10);	// Download the microcode	for (i = 0; i != ulen; i++)		for (j = 0; j != 8; j++) {			bt848->gpiodata[0] &= ~(gpio_altera_clock|gpio_altera_data);			if (u[i] & 1)				bt848->gpiodata[0] |= gpio_altera_data;			bt848->gpiodata[0] |= gpio_altera_clock;			u[i] >>= 1;		}	bt848->gpiodata[0] &= ~gpio_altera_clock;	microdelay(100);	// Initialize.	for (i = 0; i != 30; i++) {		bt848->gpiodata[0] &= ~gpio_altera_clock;		bt848->gpiodata[0] |= gpio_altera_clock;	}	bt848->gpiodata[0] &= ~(gpio_altera_clock|gpio_altera_data);	iunlock(&tv->kfirlock);	tv->gpiostate = Gpioinit;}static voidkfirreset(Tv *tv){	alterawrite(tv, 0, 0);	microdelay(10);	alterawrite(tv, 0x40000, 0);	microdelay(10);	alterawrite(tv, 0x40006, 0x80);	microdelay(10);	alterawrite(tv, 8, 1);	microdelay(10);	alterawrite(tv, 0x40004, 2);	microdelay(10);	alterawrite(tv, 4, 3);	microdelay(3);}static intkfirinitialize(Tv *tv){	// Initialize parameters?	tv->gpiostate = Gpioinit;	tv->alterareg = -1;	tv->alteraclock = 0x20000;	kfirloadu(tv, hcwAMC, sizeof hcwAMC);	kfirreset(tv);	return 1;}

⌨️ 快捷键说明

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