May 8,2009

Linux I2C 與 AD71471

AD71471 的 Device address 是 0x58,Linux driver 在處理這個時,其實會自行左移一位,因此,在 I2C_SLAVE_FORCE 的 ioctl 裡,應該是要傳 0x2c。這邊因為我暈頭,把 0x58>>1 算成 0x4c,導致我搞了好一陣子,直到 M 同事指正以後,才弄對。

再來,AD71471 在做讀寫時,Register address 與 data 都是 2 bytes,而 i2ctools 裡,處理 Register address 都只傳 1 byte(I2C_SMBUS),因此不適用在 AD71471 上。我把 Linux kernel i2c-core.c 裡的 code 翻出來改寫,改用 I2C_RDWR 來處理:
bool Write( uint16_t address, uint16_t value ) {
	int res=0;
	struct i2c_rdwr_ioctl_data msg_rdwr;
	char msgbuf0[I2C_SMBUS_BLOCK_MAX+4];
	char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];
	struct i2c_msg msg[1] = { { _address, 0, 4, msgbuf0 } };
	uint8_t* pAddr = (uint8_t*)&address;
	uint8_t* pValue = (uint8_t*)&value;

	msg_rdwr.msgs = &msg[0];
	msg_rdwr.nmsgs = 1; // write // read = 2

	// 因為 little endian,所以要作調整
	msgbuf0[0] = *(pAddr+1);
	msgbuf0[1] = *(pAddr+0);
	msgbuf0[2] = *(pValue+1); // (1)
	msgbuf0[3] = *(pValue+0);

	res = ioctl( _file, I2C_RDWR, &msg_rdwr );
	usleep(10000);

	return true;
}
bool Read( uint16_t address, uint16_t& data ) {
	int res=0;
	struct i2c_rdwr_ioctl_data msg_rdwr;
	char msgbuf0[I2C_SMBUS_BLOCK_MAX+2];
	char msgbuf1[I2C_SMBUS_BLOCK_MAX+2]={0};
	struct i2c_msg msg[2] = { { _address, 0, 2, msgbuf0 },
	                          { _address, I2C_M_RD, 2, msgbuf1 }
	                        };
	uint8_t* pAddr = (uint8_t*)&address;

	msg_rdwr.msgs = &msg[0];
	msg_rdwr.nmsgs = 1; // read = 2
	// 因為 little endian,所以要作調整
	msgbuf0[0] = *(pAddr+1);
	msgbuf0[1] = *(pAddr+0);
	res = ioctl( _file, I2C_RDWR, &msg_rdwr );
	usleep(10000);

	msg_rdwr.msgs = &msg[1];
	msg_rdwr.nmsgs = 1; // read = 2
	res = ioctl( _file, I2C_RDWR, &msg_rdwr ); #ifdef DEBUG
	data = msgbuf1[0] | (msgbuf1[1] << 8);

	return true;
}
int main( int argc, char* argv[] )
{
	int data=0;

	Read( 0x17, data );
	printf("data=%d\n", data );

	// 這邊其實不好,實際上寫 0x0052會比較清楚,這邊必須寫 0x5200,因為我在 Write() 裡有作對調,參看(1)
	Write( 0x00, 0x5200 );  
}


Posted by elleryq at 樂多Roodo! │11:57 │回應(0)引用(0)C/C++
樂多分類:網路/3C 共同主題:C/C++ 工具:編輯本文
標籤:linux,c++
Ads by Roodo! 

引用URL

http://cgi.blog.roodo.com/trackback/8891479