기존 이솝 임베디드 포럼의 지식인 서비스가 게시판 형태로 변경되었습니다.

i2c mux 제어 문의 드립니다.

하드웨어 연결은 하나의 i2c 라인에 mux 칩을 통하여 4개의 채널로 확장을 하도록 되어 있습니다.(아래 그림)

i2c_mux.JPG

linux에 기본적으로 pca9546 드라이버는 구현이 되어 있는데요

어플에서 각 각 채널별로 디바이스를 제어하고 싶은데요.

 

예를 들어 mux 칩이 없으면 아래와 같이 제어하면 되는걸로 알고 있습니다.

(아래 코드는 임태진님이 올리신 자료를 인용하였습니다.)

struct i2c_msg msg[1];

struct i2c_rdwr_ioctl_data rdwr;

nBuf[0] = reg_addr;

memcpy( nBuf+1, buf, num );


msg[0].flags = 0// write

msg[0].addr = BMP085_I2C_ADDR;

msg[0].buf = nBuf;

msg[0].len = num+1;


rdwr.msgs = msg;

rdwr.nmsgs = 1;

if ((ret = ioctl (dev, I2C_RDWR, &rdwr)) < 0) {

perror("ioctl(I2C_RDWR) : write");

eturn ret;

}


mux 칩을 사용해서 접근할려면 어떻게 해야 하는지 아시는 분 있으시면 답변 좀 부탁드립니다.

채널 ID를 설정하고 사용해야 할듯 싶은데 어떻게 해야 하는지 감이 안잡히네요.

꼭 답변 좀 부탁드립니다.

그럼 수고들 하세요.


핸폰개발자

2012.07.10 03:02:52
*.111.135.254

mux의 드라이버만 가지고 있으면 아주 쉬운 문제인데요...

방법이야 많지만 우선 2가지만 보자면

1.각 채널별로 명령어를 분리 한다.

위의 I2C_RDWR 대신에 I2C_RDWR_CH1 이런식으로 나누고 해당 명령어에서 함수 호출

2.RW명령어의 인자값에 채널 ID를 준다

rdwr = ch1

if ((ret = ioctl (dev, I2C_RDWR, &rdwr)) < 0) {

 

머 결론은 ioctl 사용법만 아시면 쉬운 문제이구요...

mux driver안에 i2c 드라이버가 있을거니 해당 함수의 write / read 함수내에서

원하시는 기능을 구현 하시면 되겠습니다.

 

고도리

2012.07.10 04:04:03
*.200.239.234

mux용 드라이버는 이미 리눅스에 있는 듯 합니다.....


아마도 질문은 어떻게 통신하는지에 관련된 내용인 듯 합니다...^^

고도리

2012.07.10 03:04:44
*.200.239.234

http://www.ipb-halle.de/~ronald/ADM5120/i2c/i2cdetect.c

파일을 참고하시기 바랍니다.


내용은 다음과 같습니다.......대충 이걸루 pca9546을 테스트 하는 듯 합니다.


/*
    i2cdetect.c - Part of i2cdetect, a user-space program to scan for I2C 
                  devices.
    Copyright (c) 1999-2001  Frodo Looijaard <[email protected]> and
                             Mark D. Studebaker <[email protected]>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>

void help(void)
{
  FILE *fptr;
  char s[100];

  fprintf(stderr,"Syntax: i2cdetect I2CBUS\n");
  fprintf(stderr,"  I2CBUS is an integer\n");
  if((fptr = fopen("/proc/bus/i2c", "r"))) {
    fprintf(stderr,"  Installed I2C busses:\n");
    while(fgets(s, 100, fptr))
      fprintf(stderr, "    %s", s);	
    fclose(fptr);
  }
}

int main(int argc, char *argv[])
{
  char *end;
  int i,j,res,i2cbus,file;
  int e1, e2, e3;
  char filename1[20];
  char filename2[20];
  char filename3[20];
  char *filename;
  long funcs;
  

  if (argc < 2) {
    fprintf(stderr,"Error: No i2c-bus specified!\n");
    help();
    exit(1);
  }

  i2cbus = strtol(argv[1],&end,0);
  if (*end) {
    fprintf(stderr,"Error: First argument not a number!\n");
    help();
    exit(1);
  }
  if ((i2cbus < 0) || (i2cbus > 0xff)) {
    fprintf(stderr,"Error: I2CBUS argument out of range!\n");
    help();
  }

/*
 * Try all three variants and give the correct error message
 * upon failure
 */

  sprintf(filename1,"/dev/i2c-%d",i2cbus);
  sprintf(filename2,"/dev/i2c%d",i2cbus);
  sprintf(filename3,"/dev/i2c/%d",i2cbus);
  if ((file = open(filename1,O_RDWR)) < 0) {
    e1 = errno;
    if ((file = open(filename2,O_RDWR)) < 0) {
      e2 = errno;
      if ((file = open(filename3,O_RDWR)) < 0) {
        e3 = errno;
        if(e1 == ENOENT && e2 == ENOENT && e3 == ENOENT) {
          fprintf(stderr,"Error: Could not open file `%s', `%s', or `%s': %s\n",
                     filename1,filename2,filename3,strerror(ENOENT));
        }
        if (e1 != ENOENT) {
          fprintf(stderr,"Error: Could not open file `%s' : %s\n",
                     filename1,strerror(e1));
          if(e1 == EACCES)
            fprintf(stderr,"Run as root?\n");
        }
        if (e2 != ENOENT) {
          fprintf(stderr,"Error: Could not open file `%s' : %s\n",
                     filename2,strerror(e2));
          if(e2 == EACCES)
            fprintf(stderr,"Run as root?\n");
        }
        if (e3 != ENOENT) {
          fprintf(stderr,"Error: Could not open file `%s' : %s\n",
                     filename3,strerror(e3));
          if(e3 == EACCES)
            fprintf(stderr,"Run as root?\n");
        }
        exit(1);
      } else {
         filename = filename3;
      }
    } else {
       filename = filename2;
    }
  } else {
    filename = filename1;
  }

  if (ioctl(file,I2C_FUNCS,&funcs) < 0) {
    fprintf(stderr,
            "Error: Could not get the adapter functionality maxtrix: %s\n",
            strerror(errno));
    exit(1);
  }
  if (! (funcs & I2C_FUNC_SMBUS_QUICK)) {
    fprintf(stderr,
            "Error: Can't use SMBus Quick Write command "
            "on this bus (ISA bus?)\n");
    exit(1);
  }
  
  fprintf(stderr,"  WARNING! This program can confuse your I2C bus, "
          "cause data loss and worse!\n");
  fprintf(stderr,"  I will probe file %s\n", filename);
  fprintf(stderr,"  You have five seconds to reconsider and press CTRL-C!\n\n");
  sleep(5);

  printf("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\n");
  for (i = 0; i < 128; i+=16) {
    printf("%02x: ",i);
    for(j = 0; j < 16; j++) {
      if (ioctl(file,I2C_SLAVE,i+j) < 0) {
        if (errno == EBUSY) {
          printf("UU ");
          continue;
        } else {
          fprintf(stderr,"Error: Could not set address to %02x: %s\n",i+j,
                  strerror(errno));
          exit(1);
        }
      }

      res = i2c_smbus_write_quick(file, I2C_SMBUS_WRITE);
      if (res < 0)
        printf("XX ");
      else
        printf("%02x ",i+j);
    }
    printf("\n");
  }
  exit(0);
}

List of Articles
번호 제목 글쓴이 날짜 조회 수
5428 device driver 에서 cmd_read 호출하는 방법 문의 [1] 훌러덩 2012-07-10 1210
» i2c mux 칩 제어 문의 file [3] 황순일 2012-07-09 2403
5426 저장매체에 bootloader image를 writing하는 방법 [3] 김경식 2012-07-07 1430
5425 sendmail arm 으로 빌드 해 보신분 훌러덩 2012-07-05 718
5424 H.264 codec 또는 영상 코덱 처리 방법 [3] 천향 2012-07-04 2208
5423 nand scrub 에 관한 질문입니다. [3] 박영기1 2012-07-04 1699
5422 ffmpeg 관련하여 examples 이 컴파일이 되지 않습니다. [1] 사랑해요 2012-07-03 1754
5421 register_console()함수에 대해서 여쭤보려고 합니다. [1] 김진희 2012-07-03 1327
5420 bcm4329 관련 문의질문.. 박한수 2012-06-30 852
5419 s3c2440 보드 관련 [4] 서연석 2012-06-29 1298
5418 sshd를 보드에 포팅하려면 어떻게 해야되나요? [4] 은민아빠 2012-06-29 1456
5417 6410보드에서 root로 로그인을 하여도 파일을 생성하거나 수정할수 ... [5] 은민아빠 2012-06-28 1330
5416 bootloader binary file과 kernel image file [1] 테크 2012-06-27 1126
5415 Linux BSP 제공되는 개발보드는 어떤 것들이 있나요? [3] 다콩 2012-06-27 1676
5414 aesop2440 보드에 대한 질문 드립니다. [2] 최고운 2012-06-27 1192
5413 [완료] Linux 커널 2.6.28에 LAN9215 드라이버 포팅해 보신분 계... [9] 박영기1 2012-06-26 1742
5412 V4L2 library가 존재하는지요 ? [1] 김경식 2012-06-26 1412
5411 6410보드에 SD메모리 용량 확인하는 법 [2] 53% 2012-06-25 1539
5410 [완료] Displaying Character on screen [16] 하루천재 2012-06-25 1319
5409 IMAGE sensor [3] 김진희 2012-06-21 1426

사용자 로그인