I2C - Linux Voyage - ALIX.2D2

OP #2658530
Lesenswert?

Guten Morgen,

ich habe gestern den ganzen Tag versucht auf meinem ALIX.2D2 ein EEPROM 
über I2C anzusprechen.

Mit i2cdetect finde ich es unter der Addresse 0x50 und ein
i2cdump -y 0 0x50 c
liefert auch den Inhalt.

Nur wenn ich es mit einem eigenem Programm machem möchte, passiert 
einfach nix auf dem I2C Bus (Oszi hängt drann).

Mein Test Code schaut so aus:
1
#include <stdio.h>
2
#include <sys/ioctl.h>
3
#include <fcntl.h>
4
#include <linux/i2c-dev.h>
5
#include <linux/i2c.h>
6

7
int main(){
8

9
  int fd,n;
10
  char buf[10];
11

12
  // Address EEPROM
13
  int addr = 0x50;
14

15
  if ((fd = open("/dev/i2c-0", O_RDWR)) < 0) {
16
    printf("open error! %d\n",fd);
17
    return 1;
18
  }
19

20
  if (ioctl(fd, I2C_SLAVE, addr) < 0) {
21
    printf("address error!\n");
22
    return 1;
23
  }
24

25
  buf[0] = 0x00;
26

27
  printf("write: ");
28
  n = write(fd, buf, 1);
29

30
  if (n != 1)
31
  printf("error! %d\n",n);
32
  else
33
  printf("0x%x, 0x%x\n", buf[0], buf[1]);
34

35
  printf("read: ");
36
  n=read(fd, buf, 1);
37

38
  if (n != 1)
39
    printf("read error! %d\n", n);
40
  else
41
    printf("0x%x\n", buf[0]);
42

43
  close(fd);
44
  return 0;
45
}

Hoffe ihr könnt mir helfen.

Danke, Markus
OP #2661159
Lesenswert?

Hallo,

mit i2cdetect finde ich das eeprom auf 0x50
1
root@voyage:/tmp# i2cdetect -y 0
2
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
3
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
4
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
5
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
6
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
7
40: -- -- -- -- -- -- -- -- -- -- -- -- UU -- -- --
8
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
9
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
10
70: -- -- -- -- -- -- -- --

nehme ich jetzt mal ein Teil von Deinem Programm:
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <unistd.h>
4
#include <fcntl.h>
5
#include <linux/i2c-dev.h>
6
#include <sys/ioctl.h>
7

8
#define DEV_I2C "/dev/i2c-0"
9
#define ADDR_EEPROM 0x50
10

11
#define DO_ERROR {printf("Error...!\n"); exit(1);}
12

13

14
int file;
15
unsigned char buffer[2], sign, dec;
16

17

18
int main(void)
19
{
20
 file = open(DEV_I2C, O_RDWR);
21
 if (file < 0) DO_ERROR;
22

23
 if (ioctl(file, I2C_SLAVE, 0x50)) DO_ERROR;
24
 buffer[0] = 0x00;
25
 if (write(file,buffer,1) !=1) DO_ERROR;
26

27
 close(file);
28
 exit(0);
29
}

Bei (write(file,buffer,1) kommt der Error

Aber warum?
Berechtigung:

root@voyage:/tmp# ls -l /dev/i2c-0
crwxrwxrwx 1 root i2c 89, 0 Jan  1  2000 /dev/i2c-0


ich arbeite als root.

Lg, Markus
Persönliche Seite #2661235
Lesenswert?

MoinMoin,

Markus C. schrieb:
> der Fehlecode lautet -1
>
nicht der Return-Code von write() sondern der Inhalt der Variable errno.

Zitat aus C-Manual zu write:

"Upon successful completion, write() [XSI] [Option Start]  and pwrite() 
[Option End] shall return the number of bytes actually written to the 
file associated with fildes. This number shall never be greater than 
nbyte. Otherwise, -1 shall be returned and errno set to indicate the 
error."

Markus C. schrieb:
> Was da auf 0x4C ist weiß ich nicht.
>
...hmm, das würde mich jetzt schon beunruhigen, da es ja offensichtlich 
ein Problem auf dem Bus gibt. ...und dieser Slave wird von jemand 
anderem unter Beschlag genommen (...UU...). Vielleicht kommt das Problem 
ja von der Seite.

Grüße Uwe
OP #2661264
Lesenswert?

Muss mal schaun wie ich den errno angezeigt bekomme..

lsmod sagt:
1
root@voyage:/backup# lsmod
2
Module                  Size  Used by
3
iptable_filter           808  1
4
ipt_MASQUERADE          1102  1
5
iptable_nat             2643  1
6
nf_nat                 10021  2 ipt_MASQUERADE,iptable_nat
7
nf_conntrack_ipv4       7295  3 iptable_nat,nf_nat
8
nf_conntrack           38707  4 ipt_MASQUERADE,iptable_nat,nf_nat,nf_conntrack_ipv4
9
nf_defrag_ipv4           795  1 nf_conntrack_ipv4
10
ip_tables               7445  2 iptable_filter,iptable_nat
11
x_tables                8882  4 iptable_filter,ipt_MASQUERADE,iptable_nat,ip_tables
12
ipv6                  192342  17
13
i2c_dev                 3482  0
14
ledtrig_netdev          2654  0
15
ledtrig_timer           1178  0
16
ledtrig_heartbeat        925  0
17
geodewdt                2051  2
18
hwmon_vid               1412  0
19
lm90                    8528  0
20
arc4                     978  2
21
ath9k                  81873  0
22
mac80211              157166  1 ath9k
23
ath9k_common            1194  1 ath9k
24
evdev                   6063  0
25
ath9k_hw              242330  2 ath9k,ath9k_common
26
ftdi_sio               24857  0
27
snd_pcm                46819  0
28
ath                    10631  2 ath9k,ath9k_hw
29
cs5535_mfgpt            2145  1 geodewdt,[permanent]
30
cs5535_gpio             3117  0
31
scx200_acb              3067  0
32
snd_timer              11838  1 snd_pcm
33
cfg80211              111132  3 ath9k,mac80211,ath
34
snd                    33773  2 snd_pcm,snd_timer
35
usbserial              21093  1 ftdi_sio
36
soundcore               3443  1 snd
37
snd_page_alloc          4817  1 snd_pcm
38
leds_alix2              1503  0
39
geode_aes               3790  0
40
pcspkr                  1215  0
41
cs5535_mfd              1772  0
42
geode_rng                800  0
43
rng_core                2274  1 geode_rng
44
rfkill                  6676  1 cfg80211
45
mfd_core                1769  1 cs5535_mfd
46
ohci_hcd               16802  0
47
ata_generic             2287  0
48
pata_cs5536             2334  0
49
pata_amd                6720  0
50
libata                124802  3 ata_generic,pata_cs5536,pata_amd
51
ide_pci_generic         1964  0
52
ehci_hcd               27368  0
53
usbcore                90394  5 ftdi_sio,usbserial,ohci_hcd,ehci_hcd
54
ssb                    31231  1 ohci_hcd
55
pcmcia                 24632  1 ssb
56
pcmcia_core             8329  1 pcmcia
57
amd74xx                 3612  1
58
via_rhine              16600  0
59
mii                     2715  1 via_rhine
60
root@voyage:/backup#

lg, markus
Persönliche Seite #2661300
Lesenswert?

MoinMoin,

ok, 0x4c ist ein LM90 (Temperatursensor).

Kante mal das Modul lm90 raus und probiere nochmal.

Der LM90 ist ein SMBus-IC, also nicht 100% I2C... Vielleicht ist das das 
Problem (kein I2C-Master, sondern ein SMBus-Master). Du kannst ja mal, 
statt dem EEPROM (welcher Typ eigentlich), den LM90 versuchen auszulesen 
(lm90-Modul muss dazu entfernt sein). Lt. Datenblatt sollte es so 
ähnlich wie ein LM75 funktionieren...

Grüße Uwe
OP #2661311
Lesenswert?

so mit: rmmod lm90 wird die adresse nicht mehr geblockt.

root@voyage:/tmp# i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- 4c -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

aber ich bekomme noch immer nicht an das eeprom drann.
Es ist ein 24AA025E48

lg, markus
Persönliche Seite #2661461
Lesenswert?

MoinMoin,

also vielleicht doch die minimalen Unterschiede zwischen I2C und 
SMBus...?

Versuche mal statt read() und write() die entsprechenden SMBus-Kommandos 
zu verwenden:

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=Documentation/i2c/dev-interface;hb=HEAD

...und berichte hier weiter, da das Thema/Problem mich langsam auch 
interessiert!

Grüße Uwe
OP #2661523
Lesenswert?

Hallo,

so ich habe nun mal weiter getestet:
Probleme mit dem smbus:
1
#include <stdio.h>
2
#include <string.h>
3
#include <stdlib.h>
4
#include <unistd.h>
5
#include <fcntl.h>
6
#include <linux/i2c-dev.h>
7
#include <sys/ioctl.h>
8
#include <sys/types.h>
9

10
int file;
11
int adapter_nr = 0;
12
char filename[20];
13

14
int main(void)
15
{
16
 snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
17
 file = open(filename, O_RDWR);
18
 if (file < 0) {perror("open"); exit(1); }
19

20
 int addr = 0x50;
21

22
 if (ioctl(file, I2C_SLAVE, addr) < 0)
23
 {
24
  printf("Error ioctl");
25
  exit(1);
26
 }
27

28
 __u8 register1 = 0x00;
29
 __s32 res;
30
 char buf[10];
31

32
 res = i2c_smbus_read_word(file, register1);
33
 if (res < 0)
34
 {
35
  printf("Error i2c_smbus_read_word");
36
  exit(1);
37
 }
38

39
close(file);
40
 exit(0);
41
}

1
root@voyage:/tmp# gcc -O3 -std=gnu99 -o i2c i2c.c
2
i2c.c: In function 'main':
3
i2c.c:32: warning: implicit declaration of function 'i2c_smbus_read_word'
4
/tmp/ccgdiq7Y.o: In function `main':
5
i2c.c:(.text+0x78): undefined reference to `i2c_smbus_read_word'
6
collect2: ld returned 1 exit status

lg, markus
OP #2661576
Lesenswert?

So schreiben kann ich nun ins eeprom.

Nur leider komme ich mit dem lesen nicht klar.

Hier mal der Code:
1
#include <stdio.h>
2
#include <string.h>
3
#include <stdlib.h>
4
#include <unistd.h>
5
#include <fcntl.h>
6
#include <linux/i2c-dev.h>
7
#include <sys/ioctl.h>
8
#include <sys/types.h>
9

10
int file;
11
int adapter_nr = 0;
12
char filename[20];
13

14
int main(void)
15
{
16
 snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
17
 file = open(filename, O_RDWR);
18
 if (file < 0) {perror("open"); exit(1); }
19

20
 int addr = 0x50;
21

22
 if (ioctl(file, I2C_SLAVE, addr) < 0)
23
 {
24
  printf("Error ioctl");
25
  exit(1);
26
 }
27

28
 __u8 register1 = 0x00;
29
 __s32 res;
30
 char buf[10];
31

32
 i2c_smbus_write_byte_data(file, register1, 0x05);
33
 
34
 close(file);
35
 exit(0);
36
}

lg, markus

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren