기존 이솝 임베디드 포럼의 지식인 서비스가 게시판 형태로 변경되었습니다.
안녕하세요
지난번 디스플레이 관련 질문을 올렸었는데 답변을 친절히 해주셔서
다시 여기 찾아오게 되었습니다.
지금 제가 안드로이드 커널에 input device로 gesture 센서를 포팅하고 있습니다.
센서 업체에서 아두이노 소스를 제공해줘서 그 내용을 바탕으로 드라이버를 짰습니다.
그런데 제가 짠 드라이버의 i2c 통신에서 에러가 발생합니다.
그래서 제가 신경 쓴 부분들이 맞는지, 제가 놓치고 있는 부분이 있는지 확인 좀 부탁드릴려고
이렇게 글을 쓰게 되었습니다. 일단 파일로 첨부 된 데이터 시트에서 Ambient Light Sensing (ALS) Part라는 파트는
사용 안하고 Gesture and Proximity Sensing (GS) Part 부분만 사용합니다.
아두이노 소스는 다음과 같습니다:
Wire.beginTransmission(0x45);
Wire.write(0x00);
Wire.write(0xc0);
Wire.write(0x62);
Wire.write(0x01);
Wire.write(0x50);
Wire.endTransmission(1);
Wire.beginTransmission(0x45);
Wire.write(0x10);
Wire.endTransmission(0);
Wire.requestFrom(0x45, 10); // request 10 bytes from slave device
i=0;
while(Wire.available())
{
unsigned char c = Wire.read(); // receive a byte as character
switch (i) {
..... 생략
제가 데이터시트를 봤을 때 slave address가 0x45였고
아두이노 소스에서 0x00 레지스터에 0xc0 과 0x62를 넣고 0x01레지스터에 0x50을 넣는걸 봐서
리눅스 드라이버에서
u8 op_data_buffer[3] = { 0x00, 0xC0, 0x62 };
u8 cycle_data_buffer[2]= { 0x01, 0x50 };
struct i2c_msg msgs[] = {
{
.addr = client->addr,
.flags = 0,
.len = 3,
.buf = op_data_buffer,
},
{
.addr = client->addr,
.flags = 0,
.len = 2,
.buf = cycle_data_buffer,
},
};
i2c_transfer(client->adapter,msgs,2); 로 보냈는데 리턴값이 음수가 나옵니다.
제가 omap4460 칩셋을 사용하는데 omap의 i2c 에러코드를 찾아보니 remote io error 라고 뜨더라고여...
그래서 omap_i2c_xfer_msg 함수 내용을 보니 bus request에 대한 no ack 인거같은데...
i2c device는
static struct i2c_board_info __initdata omap4dart_board_i2c_4_boardinfo[] = {
{
/* gesture_r */
I2C_BOARD_INFO("gesture_r", 0x45),
.irq = OMAP_GPIO_IRQ(GESTURE_R_IRQ),
},
}; 로 0x45로 슬레이브 주소값을 설정하고 i2c bus에 이 구조체를 등록해서 probe까지 뜨는것을 확인했습니다.
제가 혹시 잘못 알고있거나 빠트린것이 있는지 가르쳐주시면 정말 감사하겠습니다. ㅠㅠ
이상한 점이 slave address 는 아두이노 uno에서 연결해서 i2cdetect 로 찍어봤을 때는
슬레이브 주소가 잘 뜨는데 문제는 제가 가진 dart4460 이라는 보드에 연결했을 때는
i2cdetect 에서 주소가 뜨질 않네요.. 일단은 하드웨어 연결 문제인거 같은데...
mpu6050 이라는 IMU 센서는 gesture_r 이라는 센서와 스펙은 비슷한데 i2cdetect로 주소가 잘 뜨거든요..
그래서 비슷한 스펙을 똑같은 i2c에 똑같은 방법으로 물렸는데 하나는 되고 하나는 안되는게 어떤 문제가
있을지 감이 잘 안잡힙니다. 혹시 어떤 문제가 있을지 짐작이 가시는게 있으시면 가르쳐주셨으면 합니다. ㅠㅠ
0x45 >> 1
오른쪽 쉬프트 1개 하고 한번 해보세요.
데이타 시트 상에 write, read 주소를 0x44, 0x45 로 표현해 놓았을 것 같은데
그 device 의 address 는 앞에 7bit 0x22입니다.
리눅스 드라이버에서는 savle adress 를 적어 줘야 합니다. (read , write address 를 적어 주지 않습니다.)
(결국에는 kernel i2c framework driver가
0x22 << 1 | (READ 1)
or
0x22 << 1 | (WRITE 0) 해서 내보낼 겁니다.)
그래도 안된다면 오실로 스코프로 한번 찍어보셔야 할 것 같네요.