这篇文即调试标清视频或者说调试TVP5147和ADV7343所使用的程序名称为video_sd_playback_480i_composite
我们用的是合众达公司(SEED)的SEED-DVSD6467板,其开发包中提供了这个测试文件.大家也可在我的网盘中下载到.地址:http://yunpan.cn/QzvXRUBCeakMT
在进行复合视频480i测试的时候,对I2C的从设备地址感到比较奇怪,一般I2C设备地址都是厂家做芯片的时候给固定好的,但是在此测试程序中出现了改变.
对于TVP5147来说,数据手册上的I2C地址是0XBA即10111010,如图所示
而程序中给出的地址是0X5D即01011101,如图所示
对于ADV7343来说,数据手册上的I2C地址是0X56即01010110,如下两图所示
而程序中给出的地址是0X2B即00101011,如下图所示
也许你现在并不是很清楚它怎么个奇怪法,现在列出相应的地址为
器件 数据手册地址 程序中地址
TVP5147 10111010 01011101
ADV7343 01010110 00101011
从上面可以看出,程序中的地址相对于数据手册中的地址向右移动了一位.即在程序中I2C地址的设定对数据手册中规定的I2C地址进行了右移一位操作.为什么会这样?
经过认真的查看资料,其实也费了我好大的劲.比较笨,关键是:程序中的I2C从设备地址与数据手册中所定义的I2C地址不同了,认真看了寄存器之后终于明白了.
如下图所示.这是寄存器ICMDR--I2C Mode Register(tms320dm6467 datasheet(P339)中的所提到的一个寄存器,其文献号为SPRS403F)中设置从设备地址格式的一位
而对于ICSAR寄存器(tms320dm6467 datasheet(P339)中的所提到的一个寄存器,其文献号为SPRS403F)来看,如下两图所示
也就是说真正的I2C地址只用到此从设备地址寄存器的的后七位再加上读写位即构成从设备地址了.
下面是用示波器所捕获的I2C时钟与数据线的传输数据情况
从上图可以看出,该从设备的地址是01010110,即0x56.其中前七位为从设备地址0101011,最后一位位写信号0.接着可以看出I2C对从设备进行写子地址(SUBADDRESS)0x17,然后通过I2C对子地址(从设备寄存器)写数据(设置寄存器)0x02.在程序中的语句即为
adv7343_rset( 0x17, 0x02 ); //功能为向ADV7343寄存器0x17中写数据0x02 Int16 adv7343_rset( Uint8 reg, Uint8 reg_value ) { Int16 errors = 0; Uint8 cmd[2]; cmd[0] = reg; cmd[1] = reg_value; errors = EVMDM6467_I2C_write( ADV7343_I2C_ADDR, cmd, 2 ); _waitmsec( 10 ); return errors; } #define ADV7343_I2C_ADDR ( 0x2a | 1 ) //0x2b=00101011
从上面的设置地址可以看出0x2b=00101011的后七位.正好是数据手册中的地址0101011.放大的截图如下两图所示
那么也就是说,如果想要使用的从设备为ADV7343,我们从其datasheet上得到其IIC地址为0101011(0|1),这其中前七位为0101011,最后一位是读写位(0表示写/1表示读).严格意义上来说,IIC地址只是前面的七位即0101011,而TI的datasheet上也是这样用的,我们要使用ADV7343,就要告诉DM6467该ADV7343的IIC地址,该地址是用ICSAR寄存器来配置的.而读写位是用ICMDR寄存器的TRX位配置的.所以程序中
/*define IIC address of adv7343*/ #define ADV7343_I2C_ADDR ( 0x2a | 1 ) //0x2b=00101011 /*write by iic*/ errors = EVMDM6467_I2C_write( ADV7343_I2C_ADDR, cmd, 2 ); Int16 EVMDM6467_I2C_write( Uint16 address, Uint8* tx, Uint16 len ) { Int16 i; Uint8* tx8 = tx; I2C_ICCNT = len; // Set length I2C_ICSAR = address; // Set I2C slave address I2C_ICMDR = ICMDR_STT // Set DSP for Master Write | ICMDR_TRX // read or write!!!!!!!!!!!!! | ICMDR_MST | ICMDR_IRS | ICMDR_FREE; _wait( 10 ); for ( i = 1 ; i <= len ; i++ ) // Write from 1 byte onward { I2C_ICDXR = *tx8++; // Write 1 byte if ( _I2C_tx_ready( i2c_timeout ) ) // Wait for TX Ready return i; } I2C_ICMDR |= ICMDR_STP; // STOP return 0; }
程序中ADV7343_I2C_ADDR的值0x2a|1并没有设置读写位,这里用二进制为0101011,其实这只是设置了IIC地址,而读写位是在ICMDR寄存器中设置的.只不过EVMDM6467_I2C_write函数封装了而已.
本文转自:http://www.61ic.com/article/davinci/tms320dm646x/201104/32554.html