简单解析HI3520d的AD芯片(TP2823)模块代码

本文只是本人的个人理解,有不足的地方欢迎评论指出。代码是基于TVI的tp2823芯片驱动,版本是tp28xx_v41。

一、往tp2823芯片的0x40地址的寄存器写值,使能视频输入通道

static void tp28xx_set_reg_page(int addr, int chnl)
{
	switch(chnl) {
	case TP28XX_PAGE_V0:    HDDVR_i2c_WriteByte(addr, 0x40, 0x00); break;  // VIN1 registers
	case TP28XX_PAGE_V1:    HDDVR_i2c_WriteByte(addr, 0x40, 0x01); break;  // VIN2 registers
	case TP28XX_PAGE_V2:    HDDVR_i2c_WriteByte(addr, 0x40, 0x02); break;  // VIN3 registers
	case TP28XX_PAGE_V3:    HDDVR_i2c_WriteByte(addr, 0x40, 0x03); break;  // VIN4 registers
	case TP28XX_PAGE_VALL:  HDDVR_i2c_WriteByte(addr, 0x40, 0x04); break;  // Write All VIN1-4 regsiters
	case TP28XX_PAGE_AALL:  HDDVR_i2c_WriteByte(addr, 0x40, 0x40); break;  // Audio

	default:                HDDVR_i2c_WriteByte(addr, 0x40, 0x04); break;
	}
	
}

由图1和图2可知道:

0x00使能第一通道,0x01使能第二通道,0x02使能第三通道,0x03使能第四通道,0x04~0x07都是一次性使能四个通道,0x40同时使能四个通道和音频通道。

读取0x40地址的寄存器的值可以知道通道的使能情况,这时只看0-1位(PAGE),不管ALLWE是否为1还是为0,既是0x04和0x00都是代表第一通道已使能,0x05和0x01都是代表第二通道已使能,0x06和0x02都是代表第三通道已使能,0x07和0x03都是代表第四通道已使能。

                                                                        图1


图2

二、设置输入视频格式,往0x02地址的寄存器写值,设置之前先使能需要设置的输入通道

static int tp28xx_video_set_mode(int addr, int chnl, int fmt)
{
	int err = 0;
	unsigned char tmp = 0;

	tp28xx_set_reg_page(addr, chnl);

    tmp = HDDVR_i2c_ReadByte(addr, 0x02);
	switch(fmt) {
	case TP2802_1080P25:
		tp28xx_reg_write_table(addr, tbl_tp2802_1080p25_raster); //1080P25
		tmp &=0xF8;
		HDDVR_i2c_WriteByte(addr, 0x02, tmp);
		break;
	case TP2802_1080P30:
		tp28xx_reg_write_table(addr, tbl_tp2802_1080p30_raster); //1080P30
		tmp &=0xF8;
		HDDVR_i2c_WriteByte(addr, 0x02, tmp);
		break;
	case TP2802_720P25:
		tp28xx_reg_write_table(addr, tbl_tp2802_720p25_raster); //720P25
		tmp &=0xF8;
		tmp |=0x02;
		HDDVR_i2c_WriteByte(addr, 0x02, tmp);
		break;
	case TP2802_720P30:
		tp28xx_reg_write_table(addr, tbl_tp2802_720p30_raster); //720P30
		tmp &=0xF8;
		tmp |=0x02;
		HDDVR_i2c_WriteByte(addr, 0x02, tmp);
		break;
	case TP2802_720P50:
		tp28xx_reg_write_table(addr, tbl_tp2802_720p50_raster); //720P50
		tmp &=0xF8;
		tmp |=0x02;
		HDDVR_i2c_WriteByte(addr, 0x02, tmp);
		break;
	case TP2802_720P60:
		tp28xx_reg_write_table(addr, tbl_tp2802_720p60_raster); //720P60
		tmp &=0xF8;
		tmp |=0x02;
		HDDVR_i2c_WriteByte(addr, 0x02, tmp);
		break;
	case TP2802_720P25V2:
		tp28xx_reg_write_table(addr, tbl_tp2802_720p50_raster); //720P50
		tmp &=0xF8;
		tmp |=0x02;
		HDDVR_i2c_WriteByte(addr, 0x02, tmp);
		break;
	case TP2802_720P30V2:
		tp28xx_reg_write_table(addr, tbl_tp2802_720p60_raster); //720P60
		tmp &=0xF8;
		tmp |=0x02;
		HDDVR_i2c_WriteByte(addr, 0x02, tmp);
		break;
	case TP2802_PAL:
		tp28xx_reg_write_table(addr, tbl_tp2802_pal_raster); //PAL
		tmp &=0xF8;
		tmp |=0x07;
		HDDVR_i2c_WriteByte(addr, 0x02, tmp);
		break;
	case TP2802_NTSC:
		tp28xx_reg_write_table(addr, tbl_tp2802_ntsc_raster); //NTSC
		tmp &=0xF8;
		tmp |=0x07;
		HDDVR_i2c_WriteByte(addr, 0x02, tmp);
		break;

	default:
		err = -1;
		break;
	}
	return err;
}

由图3可知:

1080P:第0~2位全为0,tmp &=0xF8;之后再写进0x02即可。

720P  :第1位为1,tmp &=0xF8;tmp |=0x02;再写进0x02即可。

PAL制/NTSC制:第0~2位全为1,tmp &=0xF8;tmp |=0x07;再写进0x02即可。

图3

接下来往0x15、0x16、 0x17 、0x18 、0x19、0x1A 、0X1B 、0X1C 、0X1D寄存器写入相对应的值,这些值都是定义好的。


三、获取输入视频格式,从0x03处的检测寄存器(只读寄存器)读取其值,获取之前先使能需要设置的输入通道

static int tp28xx_video_get_mode(int addr, int chnl, int *fmt)
{
	unsigned char tmpFmt;
	unsigned char tmpPrg;
	int tmpRet = INVALID_FORMAT;

	tp28xx_set_reg_page(addr, chnl);

	tmpFmt  = HDDVR_i2c_ReadByte(addr, 0x03);
	tmpFmt &= 0x7; /* [2:0] - CVSTD */

	tmpPrg  = HDDVR_i2c_ReadByte(addr, 0x01);
	tmpPrg  = (tmpPrg & 0x2) >> 1; /* [2] - NINTL */

	switch(tmpFmt) {
		case TP2802_1080P25:
		case TP2802_1080P30:
		case TP2802_720P25:
		case TP2802_720P30:
		case TP2802_720P50:
		case TP2802_720P60:
		case TP2802_720P25V2:
		case TP2802_720P30V2:
			if(tmpPrg == 1) { //PROGRESSIVE VIDEO INPUT
				tmpRet = tmpFmt;
			}
		break;

		case TP2802_SD:
		case TP2802_PAL:
		case TP2802_NTSC:
			if(tmpPrg == 0) { //INTERLACED VIDEO INPUT
				tmpRet = tmpFmt;
			}
		case INVALID_FORMAT:
			break;
	}

	return tmpRet;
}

由图4可知:

第0~2位控制CVSTD,tmpFmt &= 0x7;即可获取这三位的值,接下来读取0x01寄存器的第二位来判断视频输入是隔行还是逐行,最后返回视频格式。

图4

四、获取视频是否丢失,获取之前先使能需要获取视频状态的通道

static int tp28xx_get_videoloss(int addr, int chnl)
{
	unsigned char tmp;

	tp28xx_set_reg_page(addr, chnl);

	tmp = HDDVR_i2c_ReadByte(addr, 0x01);
	tmp = (tmp & 0x80) >> 7; /* [7] - VDLOSS */
	if(!tmp) {
		if(0x08 == HDDVR_i2c_ReadByte(addr, 0x2f)) { //TEST Register
			tmp = HDDVR_i2c_ReadByte(addr, 0x04);
			if(tmp < 0x30) tmp = 0;
			else tmp = 1;
		}

	}

	return tmp;
}

读取0x01寄存器第7位的值(0=video present, 1=video loss),tmp = (tmp & 0x80) >> 7;(与上0x80再向右移7位),当tmp为0时,判断测试寄存器0x2f 的值是否等于0x08,等于的话就读取0x04寄存器的值,小于0x30返回0。大于的话返回1。

图5

五、自动增益控制,涉及寄存器0x040x060x08

static void tp2802_manual_agc(int addr, int chnl)
{
    unsigned int agc, tmp;

    HDDVR_i2c_WriteByte(addr, 0x2F, 0x02);
    agc = HDDVR_i2c_ReadByte(addr, 0x04);
    printf("AGC=0x%04x ch%02x\r\n", agc, chnl);
	agc += HDDVR_i2c_ReadByte(addr, 0x04);
	agc += HDDVR_i2c_ReadByte(addr, 0x04);
	agc += HDDVR_i2c_ReadByte(addr, 0x04);
	agc &= 0x3f0;
	agc >>=1;
    if(agc > 0x1ff) agc = 0x1ff;

	printf("AGC=0x%04x ch%02x\r\n", agc, chnl);
	HDDVR_i2c_WriteByte(addr, 0x08, agc&0xff);
	tmp = HDDVR_i2c_ReadByte(addr, 0x06);
	tmp &=0xf9;
	tmp |=(agc>>7)&0x02;
	tmp |=0x04;
	HDDVR_i2c_WriteByte(addr, 0x06,tmp);
}


以后再接着写

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值