您的位置:首页 > 编程语言

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

2015-11-30 19:24 1036 查看
本文只是本人的个人理解,有不足的地方欢迎评论指出。代码是基于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

五、自动增益控制,涉及寄存器0x04、0x06、0x08

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);
}







以后再接着写
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: