FHEM Forum

FHEM - Entwicklung => FHEM Development => Thema gestartet von: klausw am 16 Juni 2014, 16:08:25

Titel: Zugriff auf /dev/i2c-x über IOCTL und SYSREAD/SYSWRITE
Beitrag von: klausw am 16 Juni 2014, 16:08:25
Hallo,

im Modul RPII2C würde ich gern die I2C Schnittstelle direkt bedienen, ohne über Device::SMBus (das scheinbar öfters bei der Installation Probleme macht) zu gehen.
Dadurch würden bei Installation auch einige Schritte entfallen.
Hier (https://www.kernel.org/doc/Documentation/i2c/dev-interface) habe ein Beispiel für eine Implementation in C mit ioctl und read/write gefunden.
Diese Versuche ich nun in Perl umzusetzen.

Auf dem Raspberry haben die /dev/i2c-x folgende Berechtigungen:
crw-rw-rwT 1 fhem dialout  89,   0 Jun  8 13:17 i2c-0
crw-rw-rwT 1 fhem dialout  89,   1 Jun  8 13:17 i2c-1



in der 99_myUtils.pm habe ich eine kleine Testroutine geschrieben.
sub i2cread {
#system "/usr/local/bin/gpio load i2c";
my ($addr, $reg) = @_;
my $I2C_SLAVE = 0x0703;
my $I2CBusDevicePath = '/dev/i2c-1';
my $buf = $reg;
my $ret_open  = sysopen($fh, $I2CBusDevicePath, O_RDWR);
my $ret_ioctl = ioctl($fh,$I2C_SLAVE,$addr);
my $ret_read  = sysread ($fh, $buf, 1);
my $inh = $buf;
$inh =~ s/(.|\n)/sprintf("%.2X ",ord($1))/eg;
return "i2caddr: $addr | i2creg: $reg \n".
"fh: $fh | return: $ret_open | ioctlret: $ret_ioctl \n".
"sysread:  return: $ret_read | inh: $inh ($buf) | fehler: $!";
}


Das funktioniert auch in Ansätzen, allerdings wird immer der Inhalt des Registers zurückgegeben, auf das zuletzt über RPII2C zugegriffen wurde.

Beispiel:
Ein Aufruf der Routine. z.B. mit {i2cread(0x60,0x02)}
führt zu folgendem Ergebnis:
i2caddr: 96 | i2creg: 2
fh: GLOB(0x1f92148) | return: 1 | ioctlret: 0 but true
sysread:  return: 1 | inh: FF  (�) | fehler:


In diesem Fall ist FF in Wirklichkeit der Inhalt des Registers 0 (Register 2 hat den Inhalt 0x03). Die Übergabe des Registerwertes in sysread scheint nicht zu funktionieren.

Was mache ich falsch?
Titel: Antw:Zugriff auf /dev/i2c-x über IOCTL und SYSREAD/SYSWRITE
Beitrag von: klausw am 16 Juni 2014, 22:56:11
hat sich erledigt, vor sysread muss ein syswrite mit der entsprechenden Registeradresse aufgerufen werden...dann klappt es auch