Forum: PC-Programmierung I2C - Linux Voyage - ALIX.2D2


von Markus C. (ljmarkus)


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

von Uwe B. (boerge) Benutzerseite


Lesenswert?

MoinMoin.

Fragen:
* Läuft das Programm durch?
* Kommen sonst irgendwelche Fehlermeldungen?
* Hat der User Rechte auf die Devices?

Du kennst diese (meine) Seite:
http://bralug.de/wiki/BLIT2008-Board_mit_i2c-tiny-usb-Firmware

Grüße Uwe

von Markus C. (ljmarkus)


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

von Uwe B. (boerge) Benutzerseite


Lesenswert?

MoinMoin,

Markus C. schrieb:
> Bei (write(file,buffer,1) kommt der Error
>
welchen Wert hat errno?

Was ist das für ein I2C-Slave auf 0x4C und warum ist der busy?

Grüße Uwe

von Markus C. (ljmarkus)


Lesenswert?

Hallo Uwe,

der Fehlecode lautet -1

Was da auf 0x4C ist weiß ich nicht.


lg, markus

von Uwe B. (boerge) Benutzerseite


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

von Uwe B. (boerge) Benutzerseite


Lesenswert?

Uwe Berger 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.
>
...was sagt lsmod?

Grüße Uwe

von Markus C. (ljmarkus)


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

von Markus C. (ljmarkus)


Lesenswert?

Hallo Uwe,

/dev/i2c-0: Operation not supported

bekomme ich als meldung
1
 res = write(file,buffer,1);
2
 if (res < 0) {perror(DEV_I2C); }

Auf meinem 2. Board ist es auch mit 0x4C das gleiche.

lg, markus

von Uwe B. (boerge) Benutzerseite


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

von Uwe B. (boerge) Benutzerseite


Lesenswert?

Markus C. schrieb:
> Muss mal schaun wie ich den errno angezeigt bekomme..

schau mal hier: http://www.mkssoftware.com/docs/man5/errno.5.asp

Grüße Uwe

von Markus C. (ljmarkus)


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

von Uwe B. (boerge) Benutzerseite


Lesenswert?

...habe gerade das hier gefunden: 
Beitrag "ALIX 6B2 und I2C-Bus mit PCF8574 mit voyage-Linux"

Hast du eventuell auch ein Problem mit der Versorgungsspannung?

Grüße Uwe

von Markus C. (ljmarkus)


Lesenswert?

den Beitrag habe ich auch schon gefunden.

Ne das Problem habe ich nicht da die Spannung direkt vom Board kommt.

Mit i2cget und i2cput kann ich mit dem eeprom sprechen.

lg, markus

von Uwe B. (boerge) Benutzerseite


Lesenswert?

Markus C. schrieb:
> Es ist ein 24AA025E48
>
den kannte ich noch nicht...

Versuche doch erstmal den LM90 mit einem eigenen C-Programm auszulesen. 
Bei dem sollte man erwarten können, dass elektrisch alles passt.

Grüße Uwe

von Markus C. (ljmarkus)


Lesenswert?

Sobald ich auch write oder read auf die 0x4C mache bekomme ich auch die 
Meldung:

/dev/i2c-0: Operation not supported

lg, markus

von Uwe B. (boerge) Benutzerseite


Lesenswert?

MoinMoin,

Markus C. schrieb:
> res = write(file,buffer,1);
>  if (res < 0) {perror(DEV_I2C); }

nein nicht so, sondern so:
1
res = write(file,buffer,1);
2
if (res < 0) {perror("write"); }
3
4
res = read(file,buffer,1);
5
if (res < 0) {perror("read"); }

usw.

Grüße Uwe

von Markus C. (ljmarkus)


Lesenswert?

ah ok.

ändert aber nix
1
write: Operation not supported
2
read: Operation not supported

lg, markus

von asd (Gast)


Lesenswert?

Foto vom Aufbau? Was hast du wo, wie genau angeschlossen?

von Uwe B. (boerge) Benutzerseite


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

von Uwe B. (boerge) Benutzerseite


Lesenswert?

asd schrieb:
> Foto vom Aufbau? Was hast du wo, wie genau angeschlossen?
>
...da die i2c-Tools scheinbar funktionieren, ist ein Hardwareproblem 
auszuschliessen, denke ich mal!

Grüße Uwe

von Markus C. (ljmarkus)


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

von Uwe B. (boerge) Benutzerseite


Lesenswert?

vielleicht noch:

#include <linux/i2c.h>


Grüße Uwe

von Markus C. (ljmarkus)


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

von Uwe B. (boerge) Benutzerseite


Lesenswert?

Markus C. schrieb:
> So schreiben kann ich nun ins eeprom.
>
hört sich doch schon mal gut an!

Markus C. schrieb:
> Nur leider komme ich mit dem lesen nicht klar.
>
wo ist das Problem?

Grüße Uwe

von Markus C. (ljmarkus)


Lesenswert?

ja ich hatte ganz vergessen,

das wenn man was geschrieben hat, einmal close machen und dann neu 
öffnen zum lesen.

Oder habe ich jetzt falsche gedanken? Sowas wie ein Restart gibt es ja 
nicht.

lg, markus

von Markus C. (ljmarkus)


Lesenswert?

zubeachten sei noch, das die maximale Geschwindigkeit beim SMBus 100kHz 
ist.

lg, markus

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.