mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-01 19:30:31 +00:00
69cd493f17
git-svn-id: https://svn.fhem.de/fhem/trunk@23664 2b470e98-0d58-463d-a4d8-8e2adae1ed80
825 lines
35 KiB
Perl
825 lines
35 KiB
Perl
##############################################
|
|
# $Id$
|
|
package main;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use Time::HiRes qw(gettimeofday usleep);
|
|
|
|
my @clients = qw(
|
|
I2C_LCD
|
|
I2C_DS1307
|
|
I2C_PC.*
|
|
I2C_MCP.*
|
|
I2C_BM.*
|
|
I2C_SH.*
|
|
I2C_TSL.*
|
|
I2C_SUSV
|
|
I2C_LM.*
|
|
I2C_AD.*
|
|
);
|
|
|
|
my $gpioprg = "/usr/local/bin/gpio"; #WiringPi GPIO utility
|
|
my $I2C_SLAVE = 0x0703; #Variable for IOCTL (set I2C slave address)
|
|
|
|
my $libcheck_SMBus = 1;
|
|
my $check_ioctl_ph = 1;
|
|
|
|
sub RPII2C_Initialize($) {
|
|
my ($hash) = @_;
|
|
eval "use Device::SMBus;";
|
|
$libcheck_SMBus = 0 if($@);
|
|
eval {require "sys/ioctl.ph"};
|
|
$check_ioctl_ph = 0 if($@);
|
|
|
|
# Provider
|
|
$hash->{Clients} = join (':',@clients);
|
|
$hash->{I2CWrtFn} = "RPII2C_Write"; #alternative fuer IOWrite
|
|
|
|
# Normal devices
|
|
$hash->{DefFn} = "RPII2C_Define";
|
|
$hash->{UndefFn} = "RPII2C_Undef";
|
|
$hash->{GetFn} = "RPII2C_Get";
|
|
$hash->{SetFn} = "RPII2C_Set";
|
|
$hash->{AttrFn} = "RPII2C_Attr";
|
|
$hash->{NotifyFn} = "RPII2C_Notify";
|
|
$hash->{AttrList}= "do_not_notify:1,0 ignore:1,0 showtime:1,0 " .
|
|
"$readingFnAttributes";
|
|
$hash->{AttrList} .= " useHWLib:IOCTL,SMBus " if( $libcheck_SMBus && $check_ioctl_ph);
|
|
$hash->{AttrList} .= " swap_i2c0:off,on";
|
|
}
|
|
#####################################
|
|
sub RPII2C_Define($$) { #
|
|
my ($hash, $def) = @_;
|
|
my @a = split("[ \t][ \t]*", $def);
|
|
unless(@a == 3) {
|
|
my $msg = "wrong syntax: define <name> RPII2C <0|1>";
|
|
Log3 undef, 2, $msg;
|
|
return $msg;
|
|
}
|
|
$hash->{SMBus_exists} = $libcheck_SMBus if($libcheck_SMBus);
|
|
$hash->{ioctl_ph_exists} = $check_ioctl_ph if($check_ioctl_ph);
|
|
|
|
my $name = $a[0];
|
|
my $dev = $a[2];
|
|
|
|
if ($check_ioctl_ph) {
|
|
$hash->{hwfn} = \&RPII2C_HWACCESS_ioctl;
|
|
} elsif ($libcheck_SMBus) {
|
|
$hash->{hwfn} = \&RPII2C_HWACCESS;
|
|
} else {
|
|
return $name . ": Error! no library for Hardware access installed";
|
|
}
|
|
my $device = "/dev/i2c-".$dev;
|
|
if ( RPII2C_CHECK_I2C_DEVICE($device) ) {
|
|
Log3 $hash, 3, "$hash->{NAME}: file $device not accessible try to use gpio utility to fix it";
|
|
if ( defined(my $ret = RPII2C_CHECK_GPIO_UTIL($gpioprg)) ) {
|
|
Log3 $hash, 1, "$hash->{NAME}: " . $ret if $ret;
|
|
} else { #I2C Devices mit gpio utility fuer FHEM User lesbar machen
|
|
my $exp = $gpioprg.' load i2c';
|
|
$exp = `$exp`;
|
|
}
|
|
}
|
|
$hash->{NOTIFYDEV} = "global";
|
|
|
|
if($dev eq "none") {
|
|
Log3 $name, 1, "$name device is none, commands will be echoed only";
|
|
$attr{$name}{dummy} = 1;
|
|
return undef;
|
|
}
|
|
my $check = RPII2C_CHECK_I2C_DEVICE($device);
|
|
return $name . $check if $check;
|
|
|
|
$hash->{DeviceName} = $device;
|
|
$hash->{STATE} = "initialized";
|
|
return undef;
|
|
}
|
|
#####################################
|
|
sub RPII2C_Notify { #
|
|
my ($hash,$dev) = @_;
|
|
my $name = $hash->{NAME};
|
|
my $type = $hash->{TYPE};
|
|
if( grep(m/^(INITIALIZED|REREADCFG)$/, @{$dev->{CHANGED}}) ) {
|
|
RPII2C_forall_clients($hash,\&RPII2C_Init_Client,undef);;
|
|
} elsif( grep(m/^SAVE$/, @{$dev->{CHANGED}}) ) {
|
|
}
|
|
}
|
|
#####################################
|
|
sub RPII2C_forall_clients($$$) { #
|
|
my ($hash,$fn,$args) = @_;
|
|
foreach my $d ( sort keys %main::defs ) {
|
|
if ( defined( $main::defs{$d} )
|
|
&& defined( $main::defs{$d}{IODev} )
|
|
&& $main::defs{$d}{IODev} == $hash ) {
|
|
&$fn($main::defs{$d},$args);
|
|
}
|
|
}
|
|
return undef;
|
|
}
|
|
#####################################
|
|
sub RPII2C_Init_Client($@) { #
|
|
my ($hash,$args) = @_;
|
|
if (!defined $args and defined $hash->{DEF}) {
|
|
my @a = split("[ \t][ \t]*", $hash->{DEF});
|
|
$args = \@a;
|
|
}
|
|
my $name = $hash->{NAME};
|
|
Log3 $name,5,"im init client fuer $name ";
|
|
my $ret = CallFn($name,"InitFn",$hash,$args);
|
|
if ($ret) {
|
|
Log3 $name,2,"error initializing '".$hash->{NAME}."': ".$ret;
|
|
}
|
|
}
|
|
#####################################
|
|
sub RPII2C_Undef($$) { #
|
|
my ($hash, $arg) = @_;
|
|
my $name = $hash->{NAME};
|
|
|
|
foreach my $d (sort keys %defs) {
|
|
if(defined($defs{$d}) &&
|
|
defined($defs{$d}{IODev}) &&
|
|
$defs{$d}{IODev} == $hash)
|
|
{
|
|
Log3 $name, 3, "deleting port for $d";
|
|
delete $defs{$d}{IODev};
|
|
}
|
|
}
|
|
return undef;
|
|
}
|
|
#####################################
|
|
sub RPII2C_Attr(@){
|
|
my (undef, $name, $attr, $val) = @_;
|
|
my $hash = $defs{$name};
|
|
if ($attr && $attr eq 'useHWLib') {
|
|
$hash->{hwfn} = \&RPII2C_HWACCESS_ioctl if $val eq "IOCTL";
|
|
$hash->{hwfn} = \&RPII2C_HWACCESS if $val eq "SMBus";
|
|
} elsif ($attr && $attr eq 'swap_i2c0' && defined($val)) {
|
|
RPII2C_SWAPI2C0($hash,$val);
|
|
}
|
|
return undef;
|
|
}
|
|
#####################################
|
|
sub RPII2C_Set($@) { #
|
|
my ($hash, @a) = @_;
|
|
my $name = shift @a;
|
|
my $type = shift @a;
|
|
my @sets = ('writeByte', 'writeByteReg', 'writeBlock', 'writeBlockReg'); #, 'writeNBlock');
|
|
return "Unknown argument $type, choose one of " . join(" ", @sets) if @a < 2;
|
|
|
|
foreach (@a) { #Hexwerte pruefen und in Dezimalwerte wandeln
|
|
return "$name: $_ is no 1byte hexadecimal value" if $_ !~ /^(0x|)[0-9A-F]{1,2}$/xi ;
|
|
$_ = hex;
|
|
}
|
|
my $i2ca = shift @a;
|
|
return "$name: I2C Address not valid" unless ($i2ca > 3 && $i2ca < 128); #pruefe auf Hexzahl zwischen 4 und 7F
|
|
|
|
my $i2chash = { i2caddress => $i2ca, direction => "i2cbytewrite", test => "local" };
|
|
my ($reg, $nbyte, $data) = undef;
|
|
if ($type eq "writeByte") {
|
|
$data = join(" ", @a);
|
|
} elsif ($type eq "writeByteReg") {
|
|
$reg = shift @a;
|
|
$data = join(" ", @a);
|
|
} elsif ($type eq "writeBlock") {
|
|
$nbyte = int(@a);
|
|
return "$name maximal blocksize (32byte) exeeded" if $nbyte > 32;
|
|
$data = join(" ", @a);
|
|
$i2chash->{direction} = "i2cwrite";
|
|
} elsif ($type eq "writeBlockReg") {
|
|
$reg = shift @a;
|
|
$nbyte = int(@a);
|
|
return "$name maximal blocksize (32byte) exeeded" if $nbyte > 32;
|
|
$data = join(" ", @a);
|
|
$i2chash->{direction} = "i2cwrite";
|
|
} else {
|
|
return "Unknown argument $type, choose one of " . join(" ", @sets);
|
|
}
|
|
|
|
$i2chash->{reg} = $reg if defined($reg); #startadresse zum lesen
|
|
$i2chash->{nbyte} = $nbyte if defined($nbyte);
|
|
$i2chash->{data} = $data if defined($data);
|
|
&{$hash->{hwfn}}($hash, $i2chash);
|
|
undef $i2chash; #Hash loeschen
|
|
return undef;
|
|
}
|
|
#####################################
|
|
sub RPII2C_Get($@) { #
|
|
my ($hash, @a) = @_;
|
|
my $nargs = int(@a);
|
|
my $name = $hash->{NAME};
|
|
my @gets = ('read','readblock','readblockreg');
|
|
unless ( exists($a[1]) && $a[1] ne "?" && grep {/^$a[1]$/} @gets ) {
|
|
return "Unknown argument $a[1], choose one of " . join(" ", @gets);
|
|
}
|
|
if ($a[1] eq "read") {
|
|
return "use: \"get $name $a[1] <i2cAddress> [<RegisterAddress> [<Number od bytes to get>]]\"" if(@a < 3);
|
|
return "$name: I2C Address not valid" unless ( $a[2] =~ /^(0x|)([0-7]|)[0-9A-F]$/xi);
|
|
return "$name register address must be a hexvalue" if (defined($a[3]) && $a[3] !~ /^(0x|)[0-9A-F]{1,4}$/xi);
|
|
return "$name number of bytes must be decimal value" if (defined($a[4]) && $a[4] !~ /^[0-9]{1,2}$/);
|
|
my $i2chash = { i2caddress => hex($a[2]), direction => "i2cbyteread" };
|
|
$i2chash->{reg} = hex($a[3]) if defined($a[3]); #startadresse zum lesen
|
|
$i2chash->{nbyte} = $a[4] if defined($a[4]);
|
|
my $status = &{$hash->{hwfn}}($hash, $i2chash); #als Array
|
|
my $received = $i2chash->{received}; #als Scalar
|
|
undef $i2chash; #Hash loeschen
|
|
return (defined($received) ? "received : " . $received ." | " : "" ) . " transmission: $status";
|
|
} elsif ($a[1] eq "readblock") {
|
|
return "use: \"get $name $a[1] <i2cAddress> [<Number od bytes to get>]\"" if(@a < 3);
|
|
return "$name: I2C Address not valid" unless ( $a[2] =~ /^(0x|)([0-7]|)[0-9A-F]$/xi);
|
|
return "$name number of bytes must be decimal value" if (defined($a[3]) && $a[3] !~ /^[0-9]{1,2}$/);
|
|
my $i2chash = { i2caddress => hex($a[2]), direction => "i2cread" };
|
|
$i2chash->{nbyte} = $a[3] if defined($a[3]);
|
|
my $status = &{$hash->{hwfn}}($hash, $i2chash);
|
|
my $received = $i2chash->{received}; #als Scalar
|
|
undef $i2chash; #Hash loeschen
|
|
return (defined($received) ? "received : " . $received ." | " : "" ) . " transmission: $status";
|
|
} elsif ($a[1] eq "readblockreg") {
|
|
return "use: \"get $name $a[1] <i2cAddress> [<Number od bytes to get>]\"" if(@a < 2);
|
|
return "$name: I2C Address not valid" unless ( $a[2] =~ /^(0x|)([0-7]|)[0-9A-F]$/xi);
|
|
return "$name register address must be a hexvalue" if (defined($a[3]) && $a[3] !~ /^(0x|)[0-9A-F]{1,4}$/xi);
|
|
return "$name number of bytes must be decimal value" if (defined($a[4]) && $a[4] !~ /^[0-9]{1,2}$/);
|
|
my $i2chash = { i2caddress => hex($a[2]), direction => "i2cread" };
|
|
$i2chash->{reg} = hex($a[3]) if defined($a[3]);
|
|
$i2chash->{nbyte} = $a[4] if defined($a[4]);
|
|
my $status = &{$hash->{hwfn}}($hash, $i2chash);
|
|
my $received = $i2chash->{received}; #als Scalar
|
|
undef $i2chash; #Hash loeschen
|
|
return (defined($received) ? "received : " . $received ." | " : "" ) . " transmission: $status";
|
|
}
|
|
return undef;
|
|
}
|
|
#####################################
|
|
sub RPII2C_Write($$) { #wird vom Client aufgerufen
|
|
my ($hash, $clientmsg) = @_;
|
|
my $name = $hash->{NAME};
|
|
my $ankommen = "$name: vom client empfangen";
|
|
foreach my $av (keys %{$clientmsg}) { $ankommen .= "|" . $av . ": " . $clientmsg->{$av}; }
|
|
Log3 $hash, 5, $ankommen;
|
|
|
|
if ( $clientmsg->{direction} && $clientmsg->{i2caddress} ) {
|
|
$clientmsg->{$name . "_" . "SENDSTAT"} = &{$hash->{hwfn}}($hash, $clientmsg);
|
|
#$clientmsg->{$name . "_" . "SENDSTAT"} = RPII2C_HWACCESS($hash, $clientmsg);
|
|
}
|
|
|
|
foreach my $d ( sort keys %main::defs ) { #zur Botschaft passenden Clienten ermitteln geht auf Client: I2CRecFn
|
|
#Log3 $hash, 1, "d: $d". ($main::defs{$d}{IODev}? ", IODev: $main::defs{$d}{IODev}":"") . ($main::defs{$d}{I2C_Address} ? ", I2C: $main::defs{$d}{I2C_Address}":"") . ($clientmsg->{i2caddress} ? " CI2C: $clientmsg->{i2caddress}" : "");
|
|
if ( defined( $main::defs{$d} )
|
|
&& defined( $main::defs{$d}{IODev} ) && $main::defs{$d}{IODev} == $hash
|
|
&& defined( $main::defs{$d}{I2C_Address} ) && defined($clientmsg->{i2caddress})
|
|
&& $main::defs{$d}{I2C_Address} eq $clientmsg->{i2caddress} ) {
|
|
my $chash = $main::defs{$d};
|
|
Log3 $hash, 5, "$name ->Client gefunden: $d". ($main::defs{$d}{I2C_Address} ? ", I2Caddress: $main::defs{$d}{I2C_Address}":"") . ($clientmsg->{data} ? " Data: $clientmsg->{data}" : "") . ($clientmsg->{received} ? " Gelesen: $clientmsg->{received}" : "");
|
|
CallFn($d, "I2CRecFn", $chash, $clientmsg);
|
|
undef $clientmsg #Hash loeschen nachdem Daten verteilt wurden
|
|
}
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
sub RPII2C_CHECK_I2C_DEVICE {
|
|
my ($dev) = @_;
|
|
my $ret = undef;
|
|
if(-e $dev) {
|
|
if(-r $dev) {
|
|
unless(-w $dev) {
|
|
$ret = ': Error! I2C device not writable: '.$dev . '. Please install wiringpi or change access rights for fhem user';
|
|
}
|
|
} else {
|
|
$ret = ': Error! I2C device not readable: '.$dev . '. Please install wiringpi or change access rights for fhem user';
|
|
}
|
|
} else {
|
|
$ret = ': Error! I2C device not found: ' .$dev . '. Please check kernelmodules must loaded: i2c_bcm2708, i2c_dev';
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
sub RPII2C_CHECK_GPIO_UTIL {
|
|
my ($gpioprg) = @_;
|
|
my $ret = undef;
|
|
if(-e $gpioprg) {
|
|
if(-x $gpioprg) {
|
|
unless(-u $gpioprg) {
|
|
$ret = "file $gpioprg is not setuid";
|
|
}
|
|
} else {
|
|
$ret = "file $gpioprg is not executable";
|
|
}
|
|
} else {
|
|
$ret = "file $gpioprg doesnt exist";
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
sub RPII2C_SWAPI2C0 {
|
|
my ($hash,$set) = @_;
|
|
unless (defined(my $ret = RPII2C_CHECK_GPIO_UTIL($gpioprg))) {
|
|
if (defined($set) && $set eq "on") {
|
|
system "$gpioprg -g mode 0 in";
|
|
system "$gpioprg -g mode 1 in";
|
|
system "$gpioprg -g mode 28 ALT0";
|
|
system "$gpioprg -g mode 29 ALT0";
|
|
} else {
|
|
system "$gpioprg -g mode 28 in";
|
|
system "$gpioprg -g mode 29 in";
|
|
system "$gpioprg -g mode 0 ALT0";
|
|
system "$gpioprg -g mode 1 ALT0";
|
|
}
|
|
} else {
|
|
Log3 $hash, 1, $hash->{NAME} . ": " . $ret if $ret;
|
|
}
|
|
return
|
|
}
|
|
|
|
sub RPII2C_HWACCESS($$) {
|
|
my ($hash, $clientmsg) = @_;
|
|
my $status = "error";
|
|
my $inh = undef;
|
|
Log3 $hash, 5, "$hash->{NAME}: HWaccess I2CAddr: " . sprintf("0x%.2X", $clientmsg->{i2caddress});
|
|
my $dev = Device::SMBus->new(
|
|
I2CBusDevicePath => $hash->{DeviceName},
|
|
I2CDeviceAddress => hex( sprintf("%.2X", $clientmsg->{i2caddress}) ),
|
|
);
|
|
if ( defined($clientmsg->{reg}) && defined($clientmsg->{data}) && $clientmsg->{direction} eq "i2cwrite") { #blockweise beschreiben (Register)
|
|
my @data = split(" ", $clientmsg->{data});
|
|
my $dataref = \@data;
|
|
$inh = $dev->writeBlockData( $clientmsg->{reg} , $dataref );
|
|
my $wr = join(" ", @{$dataref});
|
|
Log3 $hash, 5, "$hash->{NAME}: Block schreiben Register: " . sprintf("0x%.2X", $clientmsg->{reg}) . " Inhalt: " . $wr . " N: ". int(@data) ." Returnvar.: $inh";
|
|
$status = "Ok" if $inh == 0;
|
|
} elsif (defined($clientmsg->{reg}) && defined($clientmsg->{data}) && $clientmsg->{direction} eq "i2cbytewrite") { #byteweise beschreiben (Register)
|
|
my @data = split(" ", $clientmsg->{data});
|
|
foreach (@data) {
|
|
$inh = $dev->writeByteData($clientmsg->{reg},$_);
|
|
Log3 $hash, 5, "$hash->{NAME}; Register ".sprintf("0x%.2X", $clientmsg->{reg})." schreiben - Inhalt: " .sprintf("0x%.2X",$_) . " Returnvar.: $inh";
|
|
last if $inh != 0;
|
|
$status = "Ok" if $inh == 0;
|
|
}
|
|
} elsif (defined($clientmsg->{data}) && ( $clientmsg->{direction} eq "i2cwrite" || $clientmsg->{direction} eq "i2cbytewrite" ) ) { #Byte(s) schreiben
|
|
my @data = split(" ", $clientmsg->{data});
|
|
foreach (@data) {
|
|
$inh = $dev->writeByte($_);
|
|
Log3 $hash, 5, "$hash->{NAME} Byte schreiben; Inh: " . $_ . " Returnvar.: $inh";
|
|
last if $inh != 0;
|
|
$status = "Ok" if $inh == 0;
|
|
}
|
|
} elsif (defined($clientmsg->{reg}) && ( $clientmsg->{direction} eq "i2cread" || $clientmsg->{direction} eq "i2cbyteread" ) ) { #byteweise lesen (Register)
|
|
my $nbyte = defined($clientmsg->{nbyte}) ? $clientmsg->{nbyte} : 1;
|
|
my $rmsg = "";
|
|
for (my $n = 0; $n < $nbyte; $n++) {
|
|
$inh = $dev->readByteData($clientmsg->{reg} + $n );
|
|
Log3 $hash, 5, "$hash->{NAME}; Register ".sprintf("0x%.2X", $clientmsg->{reg} + $n )." lesen - Inhalt: ".sprintf("0x%.2X",$inh);
|
|
last if ($inh < 0);
|
|
#$rmsg .= sprintf("%.2X",$inh);
|
|
$rmsg .= $inh;
|
|
$rmsg .= " " if $n <= $nbyte;
|
|
$status = "Ok" if ($n + 1) == $nbyte;
|
|
}
|
|
#@{$clientmsg->{received}} = split(" ", $rmsg) if($rmsg); #Daten als Array uebertragen
|
|
$clientmsg->{received} = $rmsg if($rmsg); #Daten als Scalar uebertragen
|
|
} elsif ($clientmsg->{direction} eq "i2cread"|| $clientmsg->{direction} eq "i2cbyteread") { #Byte lesen
|
|
my $nbyte = defined($clientmsg->{nbyte}) ? $clientmsg->{nbyte} : 1;
|
|
my $rmsg = "";
|
|
for (my $n = 0; $n < $nbyte; $n++) {
|
|
$inh = $dev->readByte();
|
|
Log3 $hash, 5, "$hash->{NAME} Byte lesen; Returnvar.: $inh";
|
|
last if ($inh < 0);
|
|
$rmsg .= $inh;
|
|
$rmsg .= " " if $n <= $nbyte;
|
|
$status = "Ok" if ($n + 1) == $nbyte;
|
|
}
|
|
#@{$clientmsg->{received}} = split(" ", $rmsg) if($rmsg); #Daten als Array uebertragen
|
|
$clientmsg->{received} = $rmsg if($rmsg); #Daten als Scalar uebertragen
|
|
}
|
|
$hash->{STATE} = $status;
|
|
$hash->{ERRORCNT} = defined($hash->{ERRORCNT}) ? $hash->{ERRORCNT} += 1 : 1 if $status ne "Ok";
|
|
$clientmsg->{$hash->{NAME} . "_" . "RAWMSG"} = $inh;
|
|
return $status;
|
|
}
|
|
#####################
|
|
|
|
sub RPII2C_HWACCESS_ioctl($$) {
|
|
my ($hash, $clientmsg) = @_;
|
|
my $status = "error";
|
|
Log3 $hash, 5, "$hash->{NAME}: HWaccess I2CAddr: " . sprintf("0x%.2X", $clientmsg->{i2caddress});
|
|
my ($fh, $msg) = undef;
|
|
|
|
my $ankommen = "$hash->{NAME}: vom client empfangen";
|
|
foreach my $av (keys %{$clientmsg}) { $ankommen .= "|" . $av . ": " . $clientmsg->{$av}; }
|
|
Log3 $hash, 5, $ankommen;
|
|
|
|
my $i2caddr = hex(sprintf "%x", $clientmsg->{i2caddress});
|
|
if ( sysopen(my $fh, $hash->{DeviceName}, O_RDWR) != 1) { #Datei oeffnen
|
|
Log3 $hash, 3, "$hash->{NAME}: HWaccess sysopen failure: $!"
|
|
} elsif( not defined( ioctl($fh,$I2C_SLAVE,$i2caddr) ) ) { #I2C Adresse per ioctl setzen
|
|
Log3 $hash, 3, "$hash->{NAME}: HWaccess (0x".unpack( "H2",pack "C", $clientmsg->{i2caddress}).") ioctl failure: $!"
|
|
} elsif ( defined($clientmsg->{data}) && $clientmsg->{direction} eq "i2cwrite") { #blockweise schreiben
|
|
my $data = defined($clientmsg->{reg}) ? chr($clientmsg->{reg}) : undef;
|
|
foreach (split(" ", $clientmsg->{data})) {
|
|
$data .= chr($_);
|
|
}
|
|
my $retval = syswrite($fh, $data, length($data));
|
|
unless (defined($retval) && $retval == length($data)) {
|
|
Log3 $hash, 3, "$hash->{NAME}: HWaccess blockweise nach 0x".unpack( "H2",pack "C", $clientmsg->{i2caddress})." schreiben, " . (defined($clientmsg->{reg}) ? "Reg: 0x". unpack( "H2",pack "C", $clientmsg->{reg}) : "") . " Inh: $clientmsg->{data}, laenge: ".length($data)."| -> syswrite failure: $!";
|
|
} else {
|
|
$status = "Ok";
|
|
Log3 $hash, 5, "$hash->{NAME}: HWaccess block schreiben, " . (defined($clientmsg->{reg}) ? "Reg: 0x". unpack( "H2",pack "C", $clientmsg->{reg}) : "") . " Inh(dec):|$clientmsg->{data}|, laenge: |".length($data)."|";
|
|
}
|
|
|
|
} elsif (defined($clientmsg->{data}) && $clientmsg->{direction} eq "i2cbytewrite") { #byteweise schreiben
|
|
my $reg = undef;
|
|
$reg = $clientmsg->{reg} if (defined($clientmsg->{reg}));
|
|
$status = "Ok";
|
|
foreach (split(" ", $clientmsg->{data})) {
|
|
my $data = (defined($reg) ? chr($reg++) : "") . chr($_);
|
|
my $retval = syswrite($fh, $data, length($data));
|
|
#Log3 $hash, 1, "retval= $retval" if $clientmsg->{test} eq "local";
|
|
unless (defined($retval) && $retval == length($data)) {
|
|
Log3 $hash, 3, "$hash->{NAME}: HWaccess byteweise nach 0x".unpack( "H2",pack "C", $clientmsg->{i2caddress})." schreiben, ". (defined($reg) ? "Reg: 0x". unpack( "H2",pack "C", ($reg - 1)) . " " : "")."Inh: 0x" . unpack( "H2",pack "C", $_) .", laenge: ".length($data)."| -> syswrite failure: $!";
|
|
$status = "error";
|
|
last;
|
|
}
|
|
Log3 $hash, 5, "$hash->{NAME}: HWaccess byteweise schreiben, ". (defined($reg) ? "Reg: 0x". unpack( "H2",pack "C", ($reg - 1)) . " " : "")."Inh: 0x" . unpack( "H2",pack "C", $_) .", laenge: ".length($data);
|
|
#Log3 $hash, 1, "$hash->{NAME}: HWaccess byteweise zu 0x".unpack( "H2",pack "C", $clientmsg->{i2caddress})." schreiben, ". (defined($reg) ? "Reg: 0x". unpack( "H2",pack "C", ($reg - 1)) . " " : "")."Inh: 0x" . unpack( "H2",pack "C", $_) .", laenge: ".length($data) if $clientmsg->{test} eq "local";
|
|
}
|
|
} elsif ($clientmsg->{direction} eq "i2cbyteread") { #byteweise lesen
|
|
my $nbyte = defined($clientmsg->{nbyte}) ? $clientmsg->{nbyte} : 1;
|
|
my $rmsg = "";
|
|
foreach (my $n = 0; $n < $nbyte; $n++) {
|
|
if ( defined($clientmsg->{reg}) ) {
|
|
Log3 $hash, 5, "$hash->{NAME}: HWaccess byteweise lesen setze Registerpointer auf " . ($clientmsg->{reg} + $n);
|
|
my $retval = syswrite($fh, chr($clientmsg->{reg} + $n), 1);
|
|
unless (defined($retval) && $retval == 1) {
|
|
Log3 $hash, 3, "$hash->{NAME}: HWaccess byteweise von 0x".unpack( "H2",pack "C", $clientmsg->{i2caddress})." lesen,". (defined($clientmsg->{reg}) ? " Reg: 0x". unpack( "H2",pack "C", ($clientmsg->{reg} + $n)) : "") . " -> syswrite failure: $!" if $!;
|
|
last;
|
|
}
|
|
}
|
|
if (defined($clientmsg->{usleep})) {
|
|
usleep($clientmsg->{usleep});
|
|
}
|
|
my $buf = undef;
|
|
my $retval = sysread($fh, $buf, 1);
|
|
unless (defined($retval) && $retval == 1) {
|
|
Log3 $hash, 3, "$hash->{NAME}: HWaccess byteweise von 0x".unpack( "H2",pack "C", $clientmsg->{i2caddress})." lesen,". (defined($clientmsg->{reg}) ? " Reg: 0x". unpack( "H2",pack "C", ($clientmsg->{reg} + $n)) : "") . " -> sysread failure: $!" if $!;
|
|
last;
|
|
}
|
|
$rmsg .= ord($buf);
|
|
$rmsg .= " " if $n <= $nbyte;
|
|
$status = "Ok" if ($n + 1) == $nbyte;
|
|
}
|
|
$clientmsg->{received} = $rmsg if($rmsg); #Daten als Scalar uebertragen
|
|
} elsif ($clientmsg->{direction} eq "i2cread") { #blockweise lesen
|
|
my $nbyte = defined($clientmsg->{nbyte}) ? $clientmsg->{nbyte} : 1;
|
|
my $rmsg = "";
|
|
if ( defined($clientmsg->{reg}) ) {
|
|
Log3 $hash, 4, "$hash->{NAME}: HWaccess blockweise lesen setze Registerpointer auf " . ($clientmsg->{reg});
|
|
my $retval = syswrite($fh, chr($clientmsg->{reg}), 1);
|
|
unless (defined($retval) && $retval == 1) {
|
|
Log3 $hash, 3, "$hash->{NAME}: HWaccess blockweise von 0x".unpack( "H2",pack "C", $clientmsg->{i2caddress})." lesen,". (defined($clientmsg->{reg}) ? " Reg: 0x". unpack( "H2",pack "C", ($clientmsg->{reg})) : "") . " -> syswrite failure: $!" if $!;
|
|
$status = "regerror";
|
|
}
|
|
}
|
|
unless ($status eq "regerror") {
|
|
usleep($clientmsg->{usleep}) if defined $clientmsg->{usleep};
|
|
my $buf = undef;
|
|
my $retval = sysread($fh, $buf, $nbyte);
|
|
unless (defined($retval) && $retval == $nbyte) {
|
|
Log3 $hash, 3, "$hash->{NAME}: HWaccess blockweise von 0x".unpack( "H2",pack "C", $clientmsg->{i2caddress})." lesen,". (defined($clientmsg->{reg}) ? " Reg: 0x". unpack( "H2",pack "C", ($clientmsg->{reg})) : "") . " -> sysread failure: $!" if $!;
|
|
} else {
|
|
$rmsg = $buf;
|
|
$rmsg =~ s/(.|\n)/sprintf("%u ",ord($1))/eg;
|
|
#Log3 $hash, 1, "test Blockweise lesen menge: |$nbyte|, inh: |$buf|, ergebnis: |$rmsg|";
|
|
$clientmsg->{received} = $rmsg if($rmsg); #Daten als Scalar uebertragen
|
|
$status = "Ok"
|
|
}
|
|
}
|
|
}
|
|
$hash->{STATE} = $status;
|
|
$hash->{ERRORCNT} = defined($hash->{ERRORCNT}) ? $hash->{ERRORCNT} += 1 : 1 if $status ne "Ok";
|
|
#$clientmsg->{$hash->{NAME} . "_" . "RAWMSG"} = $inh;
|
|
return $status;
|
|
}
|
|
|
|
|
|
=pod
|
|
=item device
|
|
=item summary accesses I2C interface via sysfs on linux
|
|
=item summary_DE Zugriff auf das I2C-Interface über sysfs auf Linux Systemen
|
|
=begin html
|
|
|
|
<a name="RPII2C"></a>
|
|
<h3>RPII2C</h3>
|
|
<ul>
|
|
<a name="RPII2C"></a>
|
|
Provides access to Raspberry Pi's I2C interfaces for some logical modules and also directly.<br>
|
|
This modul will basically work on every linux system that provides <code>/dev/i2c-x</code>.<br><br>
|
|
|
|
<b>preliminary:</b><br>
|
|
<ul>
|
|
<li>
|
|
load I2C kernel modules (choose <b>one</b> of the following options):<br>
|
|
<ul>
|
|
<li>
|
|
open /etc/modules<br>
|
|
<ul><code>sudo nano /etc/modules</code></ul><br>
|
|
add these lines<br>
|
|
<ul><code>
|
|
i2c-dev<br>
|
|
i2c-bcm2708<br>
|
|
</code></ul>
|
|
</li>
|
|
<li>
|
|
Since Kernel 3.18.x on raspberry pi and maybe on other boards too, device tree support was implemented and enabled by default.
|
|
To enable I2C support just add
|
|
<ul><code>device_tree_param=i2c0=on,i2c1=on</code></ul> to /boot/config.txt
|
|
You can also enable just one of the I2C. In this case remove the unwantet one from the line.
|
|
</li>
|
|
<li>
|
|
On Raspbian images since 2015 just start <code>sudo raspi-config</code> and enable I2C there. Parameters will be added automaticly to /boot/config.txt
|
|
</li>
|
|
reboot
|
|
</ul>
|
|
</li><br>
|
|
<li>Choose <b>only one</b> of the three follwing methodes do grant access to <code>/dev/i2c-*</code> for FHEM user:
|
|
<ul>
|
|
<li>
|
|
<code>sudo apt-get install i2c-tools<br>
|
|
sudo adduser fhem i2c<br>
|
|
sudo reboot</code><br>
|
|
</li><br>
|
|
<li>
|
|
Add following lines into <code>/etc/init.d/fhem</code> before <code>perl fhem.pl</code> line in start or into <code>/etc/rc.local</code>:<br>
|
|
<code>
|
|
sudo chown fhem /dev/i2c-*<br>
|
|
sudo chgrp dialout /dev/i2c-*<br>
|
|
sudo chmod +t /dev/i2c-*<br>
|
|
sudo chmod 660 /dev/i2c-*<br>
|
|
</code>
|
|
</li><br>
|
|
<li>
|
|
Alternatively for Raspberry Pi you can install the gpio utility from <a href="http://wiringpi.com/download-and-install/">WiringPi</a> library change access rights of I2C-Interface<br>
|
|
WiringPi installation is described here: <a href="#RPI_GPIO">RPI_GPIO.</a><br>
|
|
gpio utility will be automaticly used, if installed.<br>
|
|
Important: to use I2C-0 at P5 connector you must use attribute <code>swap_i2c0</code>.<br>
|
|
</li>
|
|
</ul>
|
|
</li><br>
|
|
<li>
|
|
<b>Optional</b>: access via IOCTL will be used (RECOMMENDED) if Device::SMBus is not present.<br>
|
|
To access the I2C-Bus via the Device::SMBus module, following steps are necessary:<br>
|
|
<ul><code>sudo apt-get install libmoose-perl<br>
|
|
sudo cpan Device::SMBus</code></ul><br>
|
|
</li>
|
|
<li>
|
|
<b>For Raspbian users only</b><br>
|
|
If you are using I2C-0 at P5 connector on Raspberry Pi model B with newer raspbian versions, including support for Raspberry Pi model B+, you must add following line to <code>/boot/cmdline.txt</code>:<br>
|
|
<ul><code>bcm2708.vc_i2c_override=1</code></ul><br>
|
|
</li>
|
|
</ul>
|
|
<a name="RPII2CDefine"></a><br>
|
|
<b>Define</b>
|
|
<ul>
|
|
<code>define <name> RPII2C <I2C Bus Number></code><br>
|
|
where <code><I2C Bus Number></code> is the number of the I2C bus that should be used (0 or 1)<br><br>
|
|
</ul>
|
|
|
|
<a name="RPII2CSet"></a>
|
|
<b>Set</b>
|
|
<ul>
|
|
<li>
|
|
Write one byte (or more bytes sequentially) directly to an I2C device (for devices that have only one register to write):<br>
|
|
<code>set <name> writeByte <I2C Address> <value></code><br><br>
|
|
</li>
|
|
<li>
|
|
Write n-bytes to an register range (as an series of single register write operations), beginning at the specified register:<br>
|
|
<code>set <name> writeByteReg <I2C Address> <Register Address> <value> [<value> [..]]</code><br><br>
|
|
</li>
|
|
<li>
|
|
Write n-bytes directly to an I2C device (as an block write operation):<br>
|
|
<code>set <name> writeBlock <I2C Address> <Register Address> <value> [<value> [..]]</code><br><br>
|
|
</li>
|
|
<li>
|
|
Write n-bytes to an register range (as an block write operation), beginning at the specified register:<br>
|
|
<code>set <name> writeBlockReg <I2C Address> <Register Address> <value> [<value> [..]]</code><br><br>
|
|
</li><br>
|
|
Examples:
|
|
<ul>
|
|
Write 0xAA to device with I2C address 0x60<br>
|
|
<code>set test1 writeByte 60 AA</code><br>
|
|
Write 0xAA to register 0x01 of device with I2C address 0x6E<br>
|
|
<code>set test1 writeByteReg 6E 01 AA</code><br>
|
|
Write 0xAA to register 0x01 of device with I2C address 0x6E, after it write 0x55 to 0x02 as two separate commands<br>
|
|
<code>set test1 writeByteReg 6E 01 AA 55</code><br>
|
|
Write 0xA4 to register 0x03, 0x00 to register 0x04 and 0xDA to register 0x05 of device with I2C address 0x60 as an block command<br>
|
|
<code>set test1 writeBlock 60 03 A4 00 DA</code><br>
|
|
|
|
</ul><br>
|
|
</ul>
|
|
|
|
<a name="RPII2CGet"></a>
|
|
<b>Get</b>
|
|
<ul>
|
|
<li>
|
|
Gets value of I2C device's registers:<br>
|
|
<code>get <name> read <I2C Address> [<Register Address> [<number of registers>]]</code><br><br>
|
|
</li>
|
|
<li>
|
|
Gets value of I2C device in blockwise mode:<br>
|
|
<code>get <name> readblock <I2C Address> [<number of registers>]</code><br><br>
|
|
</li>
|
|
<li>
|
|
Gets value of I2C device's registers in blockwise mode:<br>
|
|
<code>get <name> readblockreg <I2C Address> <Register Address> [<number of registers>]</code><br><br>
|
|
</li><br>
|
|
Examples:
|
|
<ul>
|
|
Reads byte from device with I2C address 0x60<br>
|
|
<code>get test1 read 60</code><br>
|
|
Reads register 0x01 of device with I2C address 0x6E.<br>
|
|
<code>get test1 read 6E 01 AA 55</code><br>
|
|
Reads register 0x03 to 0x06 of device with I2C address 0x60.<br>
|
|
<code>get test1 read 60 03 4</code><br>
|
|
</ul><br>
|
|
</ul><br>
|
|
|
|
<a name="RPII2CAttr"></a>
|
|
<b>Attributes</b>
|
|
<ul>
|
|
<li>swap_i2c0<br>
|
|
Swap Raspberry Pi's I2C-0 from J5 to P5 rev. B<br>
|
|
This attribute is for Raspberry Pi only and needs gpio utility from <a href="http://wiringpi.com/download-and-install/">WiringPi</a> library.<br>
|
|
Default: none, valid values: on, off<br><br>
|
|
</li>
|
|
<li>useHWLib<br>
|
|
Change hardware access method.<br>
|
|
Attribute exists only if both access methods are usable<br>
|
|
Default: IOCTL, valid values: IOCTL, SMBus<br><br>
|
|
</li>
|
|
<li><a href="#ignore">ignore</a></li>
|
|
<li><a href="#do_not_notify">do_not_notify</a></li>
|
|
<li><a href="#showtime">showtime</a></li>
|
|
</ul>
|
|
<br>
|
|
</ul>
|
|
|
|
=end html
|
|
|
|
=begin html_DE
|
|
|
|
<a name="RPII2C"></a>
|
|
<h3>RPII2C</h3>
|
|
<ul>
|
|
<a name="RPII2C"></a>
|
|
Ermöglicht den Zugriff auf die I2C Schnittstellen des Raspberry Pi, BBB, Cubie über logische Module. Register von I2C IC's können auch direkt gelesen und geschrieben werden.<br><br>
|
|
Dieses Modul funktioniert grunsätzlich auf allen Linux Systemen, die <code>/dev/i2c-x</code> bereitstellen.<br><br>
|
|
|
|
<b>Vorbereitung:</b><br>
|
|
<ul>
|
|
<li>
|
|
I2C Kernelmodule laden (chose <b>one</b> of the following options):<br>
|
|
<ul>
|
|
<li>
|
|
I2C Kernelmodule laden:<br>
|
|
modules Datei öffnen<br>
|
|
<ul><code>sudo nano /etc/modules</code></ul><br>
|
|
folgendes einfügen<br>
|
|
<ul><code>
|
|
i2c-dev<br>
|
|
i2c-bcm2708<br>
|
|
</code></ul>
|
|
</li>
|
|
<li>
|
|
Seit Kernel 3.18.x auf dem Raspberry Pi und evtl. auch auf anderen Systemen ist der "Device tree support" implementiert und standardmäßig aktiviert.
|
|
Um I2C Unterstützung zu aktivieren muß
|
|
<ul><code>device_tree_param=i2c0=on,i2c1=on</code></ul> zur /boot/config.txt hinzu gefügt werden.
|
|
Wenn nur einer der Busse genutzt wird, kann der andere einfach aus der Zeile entfernt werden.
|
|
</li>
|
|
<li>
|
|
Bei Raspbian Images seit 2015 kann der I2C Bus einfach über <code>sudo raspi-config</code> aktiviert werden. Die Parameter werden automatisch in die /boot/config.txt eingetragen.
|
|
</li>
|
|
Neustart
|
|
</ul>
|
|
</li><br>
|
|
<li><b>Eine</b> der folgenden drei Möglichkeiten wählen um dem FHEM User Zugriff auf <code>/dev/i2c-*</code> zu geben:
|
|
<ul>
|
|
<li>
|
|
<code>
|
|
sudo apt-get install i2c-tools<br>
|
|
sudo adduser fhem i2c</code><br>
|
|
</li><br>
|
|
<li>
|
|
Folgende Zeilen entweder in die Datei <code>/etc/init.d/fhem</code> vor <code>perl fhem.pl</code> in start, oder in die Datei <code>/etc/rc.local</code> eingefügen:<br>
|
|
<code>
|
|
sudo chown fhem /dev/i2c-*<br>
|
|
sudo chgrp dialout /dev/i2c-*<br>
|
|
sudo chmod +t /dev/i2c-*<br>
|
|
sudo chmod 660 /dev/i2c-*<br>
|
|
</code>
|
|
</li><br>
|
|
<li>
|
|
Für das Raspberry Pi kann alternativ das gpio Utility der <a href="http://wiringpi.com/download-and-install/">WiringPi</a> Bibliothek benutzt werden um FHEM Schreibrechte auf die I2C Schnittstelle zu bekommen.<br>
|
|
WiringPi Installation ist hier beschrieben: <a href="#RPI_GPIO">RPI_GPIO</a><br>
|
|
Das gpio Utility wird, wenn vorhanden, automatisch verwendet<br>
|
|
Wichtig: um den I2C-0 am P5 Stecker des Raspberry nutzen zu können muss das Attribut <code>swap_i2c0</code> verwendet werden.<br>
|
|
</li>
|
|
</ul>
|
|
</li><br>
|
|
<li>
|
|
<b>Optional</b>: Hardwarezugriff via IOCTL wird standardmäßig genutzt (EMPFOHLEN), wenn Device::SMBus nicht installiert ist<br>
|
|
Soll der Hardwarezugriff über das Perl Modul Device::SMBus erfolgen sind diese Schritte notwendig:<br>
|
|
<ul><code>sudo apt-get install libmoose-perl<br>
|
|
sudo cpan Device::SMBus</code></ul><br>
|
|
</li>
|
|
<li>
|
|
<b>Nur für Raspbian Nutzer</b><br>
|
|
Um I2C-0 am P5 Stecker auf Raspberry Pi modell B mit neueren Raspbian Versionen zu nutzen, welche auch das Raspberry Pi model B+ unterstützen, muss folgende Zeile in die <code>/boot/cmdline.txt</code> eingefügt werden:<br>
|
|
<ul><code>bcm2708.vc_i2c_override=1</code></ul><br>
|
|
</li>
|
|
</ul>
|
|
<a name="RPII2CDefine"></a><br>
|
|
<b>Define</b>
|
|
<ul>
|
|
<code>define <name> RPII2C <I2C Bus Number></code><br>
|
|
Die <code><I2C Bus Number></code> ist die Nummer des I2C Bus an den die I2C IC's angeschlossen werden<br><br>
|
|
</ul>
|
|
|
|
<a name="RPII2CSet"></a>
|
|
<b>Set</b>
|
|
<ul>
|
|
<li>
|
|
Schreibe ein Byte (oder auch mehrere nacheinander) direkt auf ein I2C device (manche I2C Module sind so einfach, das es nicht einmal mehrere Register gibt):<br>
|
|
<code>set <name> writeByte <I2C Address> <value></code><br><br>
|
|
</li>
|
|
<li>
|
|
Schreibe n-bytes auf einen Registerbereich (als Folge von Einzelbefehlen), beginnend mit dem angegebenen Register:<br>
|
|
<code>set <name> writeByteReg <I2C Address> <Register Address> <value> [<value> [..]]</code><br><br>
|
|
</li>
|
|
<li>
|
|
Schreibe n-bytes auf ein I2C device (als Blockoperation):<br>
|
|
<code>set <name> writeBlock <I2C Address> <value> [<value> [..]]</code><br><br>
|
|
</li>
|
|
<li>
|
|
Schreibe n-bytes auf einen Registerbereich (als Blockoperation), beginnend mit dem angegebenen Register:<br>
|
|
<code>set <name> writeBlockReg <I2C Address> <Register Address> <value> [<value> [..]]</code><br><br>
|
|
</li><br>
|
|
Beispiele:
|
|
<ul>
|
|
Schreibe 0xAA zu Modul mit I2C Addresse 0x60<br>
|
|
<code>set test1 writeByte 60 AA</code><br>
|
|
Schreibe 0xAA zu Register 0x01 des Moduls mit der I2C Adresse 0x6E<br>
|
|
<code>set test1 writeByteReg 6E 01 AA</code><br>
|
|
Schreibe 0xAA zu Register 0x01 des Moduls mit der I2C Adresse 0x6E, schreibe danach 0x55 in das Register 0x02 als einzelne Befehle<br>
|
|
<code>set test1 writeByteReg 6E 01 AA 55</code><br>
|
|
Schreibe 0xA4 zu Register 0x03, 0x00 zu Register 0x04 und 0xDA zu Register 0x05 des Moduls mit der I2C Adresse 0x60 zusammen als ein Blockbefehl<br>
|
|
<code>set test1 writeBlockReg 60 03 A4 00 DA</code><br>
|
|
</ul><br>
|
|
</ul>
|
|
|
|
<a name="RPII2CGet"></a>
|
|
<b>Get</b>
|
|
<ul>
|
|
<li>
|
|
Auslesen der Registerinhalte des I2C Moduls:<br>
|
|
<code>get <name> read <I2C Address> [<Register Address> [<number of registers>]]</code><br><br>
|
|
</li>
|
|
<li>
|
|
Blockweises Auslesen des I2C Moduls (ohne separate Register):<br>
|
|
<code>get <name> readblock <I2C Address> [<number of registers>]</code><br><br>
|
|
</li>
|
|
<li>
|
|
Blockweises Auslesen der Registerinhalte des I2C Moduls:<br>
|
|
<code>get <name> readblockreg <I2C Address> <Register Address> [<number of registers>]</code><br><br>
|
|
</li><br>
|
|
Beispiele:
|
|
<ul>
|
|
Lese Byte vom Modul mit der I2C Adresse 0x60<br>
|
|
<code>get test1 read 60</code><br>
|
|
Lese den Inhalt des Registers 0x01 vom Modul mit der I2C Adresse 0x6E.<br>
|
|
<code>get test1 read 6E 01 AA 55</code><br>
|
|
Lese den Inhalt des Registerbereichs 0x03 bis 0x06 vom Modul mit der I2C Adresse 0x60.<br>
|
|
<code>get test1 read 60 03 4</code><br>
|
|
</ul><br>
|
|
</ul><br>
|
|
|
|
<a name="RPII2CAttr"></a>
|
|
<b>Attribute</b>
|
|
<ul>
|
|
<li>swap_i2c0<br>
|
|
Umschalten von I2C-0 des Raspberry Pi Rev. B von J5 auf P5<br>
|
|
Dieses Attribut ist nur für das Raspberry Pi vorgesehen und benötigt das gpio utility wie unter dem Punkt Vorbereitung beschrieben.<br>
|
|
Standard: keiner, gültige Werte: on, off<br><br>
|
|
</li>
|
|
<li>useHWLib<br>
|
|
Ändern der Methode des Hardwarezugriffs.<br>
|
|
Dieses Attribut existiert nur, wenn beide Zugriffsmethoden verfügbar sind<br>
|
|
Standard: IOCTL, gültige Werte: IOCTL, SMBus<br><br>
|
|
</li>
|
|
<li><a href="#ignore">ignore</a></li>
|
|
<li><a href="#do_not_notify">do_not_notify</a></li>
|
|
<li><a href="#showtime">showtime</a></li>
|
|
</ul>
|
|
<br>
|
|
</ul>
|
|
|
|
=end html_DE
|
|
|
|
1; |