Picproje Elektronik Sitesi

BİLGİSAYAR => Linux => Konuyu başlatan: sseedat - 19 Temmuz 2014, 22:47:00

Başlık: linux i2c ile istenilen adresten data okuma yada yazma
Gönderen: sseedat - 19 Temmuz 2014, 22:47:00
merhaba arkadaşlar linux i2c ile slave bir cihazın istediğim adresine nasıl veri yazıp okuyabilirim

Başlık: Ynt: linux i2c ile istenilen adresten data okuma yada yazma
Gönderen: mehmet - 20 Temmuz 2014, 01:02:32
Normalde pc nin kendi sensorleri için lm_sensors paketi mevcut. Ancak
i2cdetect, i2cget, i2cset gibi komutlar da kullanılabilmekte...
Başlık: Ynt: linux i2c ile istenilen adresten data okuma yada yazma
Gönderen: sseedat - 20 Temmuz 2014, 01:18:34
i2cset ile konsoldan istediğim yere veri yazabiliyorum fakat benim istediğim c codları içinde write,read gibi fonksiyonlarla yazmak

   char buff[16]={0};
   buff[0]=0x03;  //adres
   buff[1]=8;       //data
//    buff[2]=ConvertDecimalToHex(0x80);
//    buff[3]=0;
//    buff[4]=0;
//    buff[5]=0;
//    buff[6]=0;
//    buff[7]=0;


   sprintf(busPath,"/dev/i2c-%d",I2C_BUS);

   if((fd=open(busPath,O_WRONLY))<0)
   {
      perror("cannot open i2c");
      exit(0);
   }

   if((fd=ioctl(fd,I2C_SLAVE,WDEVICE_ADRESS>>1))<0)
   {
      perror("ioctl");
      exit(0);
   }
   write(fd,buff,2);
   close(fd);

burda write ile önce adresi gönderip ardından datayı göndermek fakat bir türlü slave cihaza veri yazamadım.
Başlık: Ynt: linux i2c ile istenilen adresten data okuma yada yazma
Gönderen: mehmet - 20 Temmuz 2014, 01:51:46
İlgili cihazın katakoğundan nasıl yazılır nasıl
okunur bunu öğrenmelisiniz öncelikle. Yazmak ve
okumak için belli işlemleri yapmanız gerekmekte...
Başlık: Ynt: linux i2c ile istenilen adresten data okuma yada yazma
Gönderen: sseedat - 20 Temmuz 2014, 15:12:22
kataloğa göre  slave adres + register adres + data şeklinde bende o şekilde veri yolluyorum fakat olmuyor nedense.

slave cihaz PCF8563 RTC entegresi karmaşık birşey de değil aslında
Başlık: Ynt: linux i2c ile istenilen adresten data okuma yada yazma
Gönderen: mehmet - 20 Temmuz 2014, 17:14:46
ACK, NACK bunlarda olmalı.
Pc bağlantınızı nasıl yaptınız...
Başlık: Ynt: linux i2c ile istenilen adresten data okuma yada yazma
Gönderen: aykuto - 01 Ağustos 2014, 11:33:19
Ben aşağıdaki fonksiyonları kullanıyorum. Kendi yazılımım içinden kopyalayarak aldım, derlemeyi tekrar deneyemedim.


#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

int main(void)
{
  int f;
  unsigned char slaveadr;
  unsigned char reg;
  unsigned char val;

   f = open("/dev/i2c-0", O_RDWR);
   slaveadr=0x18;
   reg=0x20;
   val=0x47;
   set_i2c_register(f,slaveadr,reg,val);

   val=0;
   get_i2c_register(f,slaveadr,reg,&val);

   printf("Okunan deger:%d\r\n",val);
   close(f);
}

static int set_i2c_register(int file,
                            unsigned char addr,
                            unsigned char reg,
                            unsigned char value) {

    unsigned char outbuf[2];
    struct i2c_rdwr_ioctl_data packets;
    struct i2c_msg messages[1];

    messages[0].addr  = addr;
    messages[0].flags = 0;
    messages[0].len   = sizeof(outbuf);
    messages[0].buf   = outbuf;

    /* The first byte indicates which register we'll write */
    outbuf[0] = reg;

    /*
     * The second byte indicates the value to write.  Note that for many
     * devices, we can write multiple, sequential registers at once by
     * simply making outbuf bigger.
     */
    outbuf[1] = value;

    /* Transfer the i2c packets to the kernel and verify it worked */
    packets.msgs  = messages;
    packets.nmsgs = 1;
    if(ioctl(file, I2C_RDWR, &packets) < 0) {
        perror("Unable to send data");
        return 1;
    }

    return 0;
}


static int get_i2c_register(int file,
                            unsigned char addr,
                            unsigned char reg,
                            unsigned char *val) {
    unsigned char inbuf, outbuf;
    struct i2c_rdwr_ioctl_data packets;
    struct i2c_msg messages[2];

    /*
     * In order to read a register, we first do a "dummy write" by writing
     * 0 bytes to the register we want to read from.  This is similar to
     * the packet in set_i2c_register, except it's 1 byte rather than 2.
     */
    outbuf = reg;
    messages[0].addr  = addr;
    messages[0].flags = 0;
    messages[0].len   = sizeof(outbuf);
    messages[0].buf   = &outbuf;

    /* The data will get returned in this structure */
    messages[1].addr  = addr;
    messages[1].flags = I2C_M_RD/* | I2C_M_NOSTART*/;
    messages[1].len   = sizeof(inbuf);
    messages[1].buf   = &inbuf;

    /* Send the request to the kernel and get the result back */
    packets.msgs      = messages;
    packets.nmsgs     = 2;
    if(ioctl(file, I2C_RDWR, &packets) < 0) {
        perror("Unable to send data");
        return 1;
    }
    *val = inbuf;

    return 0;
}