简单解析HI3520d的AD芯片(TP2823)模块代码
2015-11-30 19:24
1036 查看
本文只是本人的个人理解,有不足的地方欢迎评论指出。代码是基于TVI的tp2823芯片驱动,版本是tp28xx_v41。
一、往tp2823芯片的0x40地址的寄存器写值,使能视频输入通道
由图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地址的寄存器写值,设置之前先使能需要设置的输入通道
由图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处的检测寄存器(只读寄存器)读取其值,获取之前先使能需要设置的输入通道
由图4可知:
第0~2位控制CVSTD,tmpFmt &= 0x7;即可获取这三位的值,接下来读取0x01寄存器的第二位来判断视频输入是隔行还是逐行,最后返回视频格式。
图4
四、获取视频是否丢失,获取之前先使能需要获取视频状态的通道
读取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
以后再接着写
一、往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); }
以后再接着写
相关文章推荐
- 从头认识java-11.1 不变的字符串
- 指针访问真的高效吗
- 我在PHP中混淆的三组函数总结(htmlentities,html_entity_decode,addslashes)
- 浅析Java内存模型
- googletest 学习笔记
- 黑马程序员——C语言循环、switch与if语句笔记和习题
- Ubuntu 14.04下OpenCV 3.0+Python 2.7安装测试
- Java: byte short 如何正确异或!
- Eclipse中配置反编译插件Jadclipse
- 【粗解】【通信编码】卷积编码器的简单实现
- C/C++结构体struct详解
- JDK并发工具类源码学习系列——SynchronousQueue
- Spring使用Cache
- Eclipse启动时报错:No java virtual machine
- Springmvc 测试类(注解)
- 我所理解的设计模式(C++实现)——观察者模式(Observer Pattern)
- JavaEE_Mybatis_SpringMVC_Mybatis_lesson10__利用foreach标签_拼接SQL串,实现IN(X,Y,Z,...的形式)
- Django学习记录之Django 1.8 教程(我只是官网的搬运工)Tutorial Part 2
- VBS自学(四)
- python题目:一个小小的猜名有戏