00_RPII2C.pm 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. ##############################################
  2. # $Id: 00_RPII2C.pm 15021 2017-09-06 19:48:55Z klausw $
  3. package main;
  4. use strict;
  5. use warnings;
  6. use Time::HiRes qw(gettimeofday usleep);
  7. #use Device::SMBus;
  8. #my $clientsI2C = ":I2C_PC.*:I2C_SHT21:I2C_MCP23017:I2C_BMP180:";
  9. my @clients = qw(
  10. I2C_LCD
  11. I2C_DS1307
  12. I2C_PC.*
  13. I2C_MCP.*
  14. I2C_BME280
  15. I2C_BMP180
  16. I2C_SHT21
  17. I2C_TSL2561
  18. I2C_SUSV
  19. I2C_LM.*
  20. );
  21. my $gpioprg = "/usr/local/bin/gpio"; #WiringPi GPIO utility
  22. my $I2C_SLAVE = 0x0703; #Variable for IOCTL (set I2C slave address)
  23. #my %matchListI2C = ( #kann noch weg?
  24. # "1:I2C_PCF8574"=> ".*",
  25. # "2:FHT" => "^81..(04|09|0d)..(0909a001|83098301|c409c401)..",
  26. #);
  27. my $libcheck_SMBus = 1;
  28. my $check_ioctl_ph = 1;
  29. sub RPII2C_Initialize($) {
  30. my ($hash) = @_;
  31. eval "use Device::SMBus;";
  32. $libcheck_SMBus = 0 if($@);
  33. eval {require "sys/ioctl.ph"};
  34. $check_ioctl_ph = 0 if($@);
  35. # Provider
  36. $hash->{Clients} = join (':',@clients);
  37. #$hash->{WriteFn} = "RPII2C_Write"; #wird vom client per IOWrite($@) aufgerufen
  38. $hash->{I2CWrtFn} = "RPII2C_Write"; #zum testen als alternative fuer IOWrite
  39. # Normal devices
  40. $hash->{DefFn} = "RPII2C_Define";
  41. $hash->{UndefFn} = "RPII2C_Undef";
  42. $hash->{GetFn} = "RPII2C_Get";
  43. $hash->{SetFn} = "RPII2C_Set";
  44. $hash->{AttrFn} = "RPII2C_Attr";
  45. $hash->{NotifyFn} = "RPII2C_Notify";
  46. $hash->{AttrList}= "do_not_notify:1,0 ignore:1,0 showtime:1,0 " .
  47. "$readingFnAttributes";
  48. $hash->{AttrList} .= " useHWLib:IOCTL,SMBus " if( $libcheck_SMBus && $check_ioctl_ph);
  49. $hash->{AttrList} .= " swap_i2c0:off,on";
  50. }
  51. #####################################
  52. sub RPII2C_Define($$) { #
  53. my ($hash, $def) = @_;
  54. my @a = split("[ \t][ \t]*", $def);
  55. unless(@a == 3) {
  56. my $msg = "wrong syntax: define <name> RPII2C <0|1>";
  57. Log3 undef, 2, $msg;
  58. return $msg;
  59. }
  60. $hash->{SMBus_exists} = $libcheck_SMBus if($libcheck_SMBus);
  61. $hash->{ioctl_ph_exists} = $check_ioctl_ph if($check_ioctl_ph);
  62. my $name = $a[0];
  63. my $dev = $a[2];
  64. if ($check_ioctl_ph) {
  65. $hash->{hwfn} = \&RPII2C_HWACCESS_ioctl;
  66. } elsif ($libcheck_SMBus) {
  67. $hash->{hwfn} = \&RPII2C_HWACCESS;
  68. } else {
  69. return $name . ": Error! no library for Hardware access installed";
  70. }
  71. my $device = "/dev/i2c-".$dev;
  72. if ( RPII2C_CHECK_I2C_DEVICE($device) ) {
  73. Log3 $hash, 3, "$hash->{NAME}: file $device not accessible try to use gpio utility to fix it";
  74. if ( defined(my $ret = RPII2C_CHECK_GPIO_UTIL($gpioprg)) ) {
  75. Log3 $hash, 1, "$hash->{NAME}: " . $ret if $ret;
  76. } else { #I2C Devices mit gpio utility fuer FHEM User lesbar machen
  77. my $exp = $gpioprg.' load i2c';
  78. $exp = `$exp`;
  79. }
  80. }
  81. $hash->{NOTIFYDEV} = "global";
  82. #$hash->{Clients} = $clientsI2C;
  83. #$hash->{MatchList} = \%matchListI2C;
  84. if($dev eq "none") {
  85. Log3 $name, 1, "$name device is none, commands will be echoed only";
  86. $attr{$name}{dummy} = 1;
  87. return undef;
  88. }
  89. my $check = RPII2C_CHECK_I2C_DEVICE($device);
  90. return $name . $check if $check;
  91. $hash->{DeviceName} = $device;
  92. $hash->{STATE} = "initialized";
  93. return undef;
  94. }
  95. #####################################
  96. sub RPII2C_Notify { #
  97. my ($hash,$dev) = @_;
  98. my $name = $hash->{NAME};
  99. my $type = $hash->{TYPE};
  100. if( grep(m/^(INITIALIZED|REREADCFG)$/, @{$dev->{CHANGED}}) ) {
  101. RPII2C_forall_clients($hash,\&RPII2C_Init_Client,undef);;
  102. } elsif( grep(m/^SAVE$/, @{$dev->{CHANGED}}) ) {
  103. }
  104. }
  105. #####################################
  106. sub RPII2C_forall_clients($$$) { #
  107. my ($hash,$fn,$args) = @_;
  108. foreach my $d ( sort keys %main::defs ) {
  109. if ( defined( $main::defs{$d} )
  110. && defined( $main::defs{$d}{IODev} )
  111. && $main::defs{$d}{IODev} == $hash ) {
  112. &$fn($main::defs{$d},$args);
  113. }
  114. }
  115. return undef;
  116. }
  117. #####################################
  118. sub RPII2C_Init_Client($@) { #
  119. my ($hash,$args) = @_;
  120. if (!defined $args and defined $hash->{DEF}) {
  121. my @a = split("[ \t][ \t]*", $hash->{DEF});
  122. $args = \@a;
  123. }
  124. my $name = $hash->{NAME};
  125. Log3 $name,5,"im init client fuer $name ";
  126. my $ret = CallFn($name,"InitFn",$hash,$args);
  127. if ($ret) {
  128. Log3 $name,2,"error initializing '".$hash->{NAME}."': ".$ret;
  129. }
  130. }
  131. #####################################
  132. sub RPII2C_Undef($$) { #
  133. my ($hash, $arg) = @_;
  134. my $name = $hash->{NAME};
  135. foreach my $d (sort keys %defs) {
  136. if(defined($defs{$d}) &&
  137. defined($defs{$d}{IODev}) &&
  138. $defs{$d}{IODev} == $hash)
  139. {
  140. Log3 $name, 3, "deleting port for $d";
  141. delete $defs{$d}{IODev};
  142. }
  143. }
  144. return undef;
  145. }
  146. #####################################
  147. sub RPII2C_Attr(@){
  148. my (undef, $name, $attr, $val) = @_;
  149. my $hash = $defs{$name};
  150. if ($attr && $attr eq 'useHWLib') {
  151. $hash->{hwfn} = \&RPII2C_HWACCESS_ioctl if $val eq "IOCTL";
  152. $hash->{hwfn} = \&RPII2C_HWACCESS if $val eq "SMBus";
  153. } elsif ($attr && $attr eq 'swap_i2c0' && defined($val)) {
  154. RPII2C_SWAPI2C0($hash,$val);
  155. }
  156. return undef;
  157. }
  158. #####################################
  159. sub RPII2C_Set($@) { #writeBlock noch nicht fertig
  160. my ($hash, @a) = @_;
  161. my $name = shift @a;
  162. my $type = shift @a;
  163. my @sets = ('writeByte', 'writeByteReg', 'writeBlock', 'writeBlockReg'); #, 'writeNBlock');
  164. return "Unknown argument $type, choose one of " . join(" ", @sets) if @a < 2;
  165. foreach (@a) { #Hexwerte pruefen und in Dezimalwerte wandeln
  166. return "$name: $_ is no 1byte hexadecimal value" if $_ !~ /^(0x|)[0-9A-F]{1,2}$/xi ;
  167. $_ = hex;
  168. }
  169. my $i2ca = shift @a;
  170. return "$name: I2C Address not valid" unless ($i2ca > 3 && $i2ca < 128); #pruefe auf Hexzahl zwischen 4 und 7F
  171. my $i2chash = { i2caddress => $i2ca, direction => "i2cbytewrite", test => "local" };
  172. my ($reg, $nbyte, $data) = undef;
  173. if ($type eq "writeByte") {
  174. $data = join(" ", @a);
  175. } elsif ($type eq "writeByteReg") {
  176. $reg = shift @a;
  177. $data = join(" ", @a);
  178. } elsif ($type eq "writeBlock") {
  179. $nbyte = int(@a);
  180. return "$name maximal blocksize (32byte) exeeded" if $nbyte > 32;
  181. $data = join(" ", @a);
  182. $i2chash->{direction} = "i2cwrite";
  183. } elsif ($type eq "writeBlockReg") {
  184. $reg = shift @a;
  185. $nbyte = int(@a);
  186. return "$name maximal blocksize (32byte) exeeded" if $nbyte > 32;
  187. $data = join(" ", @a);
  188. $i2chash->{direction} = "i2cwrite";
  189. } else {
  190. return "Unknown argument $type, choose one of " . join(" ", @sets);
  191. }
  192. $i2chash->{reg} = $reg if defined($reg); #startadresse zum lesen
  193. $i2chash->{nbyte} = $nbyte if defined($nbyte);
  194. $i2chash->{data} = $data if defined($data);
  195. &{$hash->{hwfn}}($hash, $i2chash);
  196. undef $i2chash; #Hash loeschen
  197. return undef;
  198. }
  199. ##################################### nicht fertig!
  200. sub RPII2C_Get($@) { #
  201. my ($hash, @a) = @_;
  202. my $nargs = int(@a);
  203. my $name = $hash->{NAME};
  204. my @gets = ('read','readblock','readblockreg');
  205. unless ( exists($a[1]) && $a[1] ne "?" && grep {/^$a[1]$/} @gets ) {
  206. return "Unknown argument $a[1], choose one of " . join(" ", @gets);
  207. }
  208. if ($a[1] eq "read") {
  209. return "use: \"get $name $a[1] <i2cAddress> [<RegisterAddress> [<Number od bytes to get>]]\"" if(@a < 3);
  210. return "$name: I2C Address not valid" unless ( $a[2] =~ /^(0x|)([0-7]|)[0-9A-F]$/xi);
  211. return "$name register address must be a hexvalue" if (defined($a[3]) && $a[3] !~ /^(0x|)[0-9A-F]{1,4}$/xi);
  212. return "$name number of bytes must be decimal value" if (defined($a[4]) && $a[4] !~ /^[0-9]{1,2}$/);
  213. my $i2chash = { i2caddress => hex($a[2]), direction => "i2cbyteread" };
  214. $i2chash->{reg} = hex($a[3]) if defined($a[3]); #startadresse zum lesen
  215. $i2chash->{nbyte} = $a[4] if defined($a[4]);
  216. #Log3 $hash, 1, "Reg: ". $i2chash->{reg};
  217. #my $status = RPII2C_HWACCESS_ioctl($hash, $i2chash);
  218. my $status = &{$hash->{hwfn}}($hash, $i2chash);
  219. #my $received = join(" ", @{$i2chash->{received}}); #als Array
  220. my $received = $i2chash->{received}; #als Scalar
  221. undef $i2chash; #Hash loeschen
  222. return (defined($received) ? "received : " . $received ." | " : "" ) . " transmission: $status";
  223. } elsif ($a[1] eq "readblock") {
  224. return "use: \"get $name $a[1] <i2cAddress> [<Number od bytes to get>]\"" if(@a < 3);
  225. return "$name: I2C Address not valid" unless ( $a[2] =~ /^(0x|)([0-7]|)[0-9A-F]$/xi);
  226. return "$name number of bytes must be decimal value" if (defined($a[3]) && $a[3] !~ /^[0-9]{1,2}$/);
  227. my $i2chash = { i2caddress => hex($a[2]), direction => "i2cread" };
  228. $i2chash->{nbyte} = $a[3] if defined($a[3]);
  229. my $status = &{$hash->{hwfn}}($hash, $i2chash);
  230. my $received = $i2chash->{received}; #als Scalar
  231. undef $i2chash; #Hash loeschen
  232. return (defined($received) ? "received : " . $received ." | " : "" ) . " transmission: $status";
  233. } elsif ($a[1] eq "readblockreg") {
  234. return "use: \"get $name $a[1] <i2cAddress> [<Number od bytes to get>]\"" if(@a < 2);
  235. return "$name: I2C Address not valid" unless ( $a[2] =~ /^(0x|)([0-7]|)[0-9A-F]$/xi);
  236. return "$name register address must be a hexvalue" if (defined($a[3]) && $a[3] !~ /^(0x|)[0-9A-F]{1,4}$/xi);
  237. return "$name number of bytes must be decimal value" if (defined($a[4]) && $a[4] !~ /^[0-9]{1,2}$/);
  238. my $i2chash = { i2caddress => hex($a[2]), direction => "i2cread" };
  239. $i2chash->{reg} = hex($a[3]) if defined($a[3]);
  240. $i2chash->{nbyte} = $a[4] if defined($a[4]);
  241. my $status = &{$hash->{hwfn}}($hash, $i2chash);
  242. my $received = $i2chash->{received}; #als Scalar
  243. undef $i2chash; #Hash loeschen
  244. return (defined($received) ? "received : " . $received ." | " : "" ) . " transmission: $status";
  245. }
  246. return undef;
  247. }
  248. #####################################
  249. sub RPII2C_Write($$) { #wird vom Client aufgerufen
  250. my ($hash, $clientmsg) = @_;
  251. my $name = $hash->{NAME};
  252. my $ankommen = "$name: vom client empfangen";
  253. foreach my $av (keys %{$clientmsg}) { $ankommen .= "|" . $av . ": " . $clientmsg->{$av}; }
  254. Log3 $hash, 5, $ankommen;
  255. if ( $clientmsg->{direction} && $clientmsg->{i2caddress} ) {
  256. $clientmsg->{$name . "_" . "SENDSTAT"} = &{$hash->{hwfn}}($hash, $clientmsg);
  257. #$clientmsg->{$name . "_" . "SENDSTAT"} = RPII2C_HWACCESS($hash, $clientmsg);
  258. }
  259. foreach my $d ( sort keys %main::defs ) { #zur Botschaft passenden Clienten ermitteln geht auf Client: I2CRecFn
  260. #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}" : "");
  261. if ( defined( $main::defs{$d} )
  262. && defined( $main::defs{$d}{IODev} ) && $main::defs{$d}{IODev} == $hash
  263. && defined( $main::defs{$d}{I2C_Address} ) && defined($clientmsg->{i2caddress})
  264. && $main::defs{$d}{I2C_Address} eq $clientmsg->{i2caddress} ) {
  265. my $chash = $main::defs{$d};
  266. 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}" : "");
  267. CallFn($d, "I2CRecFn", $chash, $clientmsg);
  268. undef $clientmsg #Hash loeschen nachdem Daten verteilt wurden
  269. }
  270. }
  271. return undef;
  272. }
  273. #####################################
  274. #FRM_forall_clients($$$)
  275. #{
  276. # my ($hash,$fn,$args) = @_;
  277. # foreach my $d ( sort keys %main::defs ) {
  278. # if ( defined( $main::defs{$d} )
  279. # && defined( $main::defs{$d}{IODev} )
  280. # && $main::defs{$d}{IODev} == $hash ) {
  281. # &$fn($main::defs{$d},$args); #funktion mit Varianblennamen von $fn ausfuehren
  282. # }
  283. # }
  284. # return undef;
  285. #}
  286. #####################################
  287. sub RPII2C_CHECK_I2C_DEVICE {
  288. my ($dev) = @_;
  289. my $ret = undef;
  290. if(-e $dev) {
  291. if(-r $dev) {
  292. unless(-w $dev) {
  293. $ret = ': Error! I2C device not writable: '.$dev . '. Please install wiringpi or change access rights for fhem user';
  294. }
  295. } else {
  296. $ret = ': Error! I2C device not readable: '.$dev . '. Please install wiringpi or change access rights for fhem user';
  297. }
  298. } else {
  299. $ret = ': Error! I2C device not found: ' .$dev . '. Please check kernelmodules must loaded: i2c_bcm2708, i2c_dev';
  300. }
  301. return $ret;
  302. }
  303. sub RPII2C_CHECK_GPIO_UTIL {
  304. my ($gpioprg) = @_;
  305. my $ret = undef;
  306. if(-e $gpioprg) {
  307. if(-x $gpioprg) {
  308. unless(-u $gpioprg) {
  309. $ret = "file $gpioprg is not setuid";
  310. }
  311. } else {
  312. $ret = "file $gpioprg is not executable";
  313. }
  314. } else {
  315. $ret = "file $gpioprg doesnt exist";
  316. }
  317. return $ret;
  318. }
  319. sub RPII2C_SWAPI2C0 {
  320. my ($hash,$set) = @_;
  321. unless (defined(my $ret = RPII2C_CHECK_GPIO_UTIL($gpioprg))) {
  322. if (defined($set) && $set eq "on") {
  323. system "$gpioprg -g mode 0 in";
  324. system "$gpioprg -g mode 1 in";
  325. system "$gpioprg -g mode 28 ALT0";
  326. system "$gpioprg -g mode 29 ALT0";
  327. } else {
  328. system "$gpioprg -g mode 28 in";
  329. system "$gpioprg -g mode 29 in";
  330. system "$gpioprg -g mode 0 ALT0";
  331. system "$gpioprg -g mode 1 ALT0";
  332. }
  333. } else {
  334. Log3 $hash, 1, $hash->{NAME} . ": " . $ret if $ret;
  335. }
  336. return
  337. }
  338. sub RPII2C_HWACCESS($$) {
  339. my ($hash, $clientmsg) = @_;
  340. my $status = "error";
  341. my $inh = undef;
  342. Log3 $hash, 5, "$hash->{NAME}: HWaccess I2CAddr: " . sprintf("0x%.2X", $clientmsg->{i2caddress});
  343. my $dev = Device::SMBus->new(
  344. I2CBusDevicePath => $hash->{DeviceName},
  345. I2CDeviceAddress => hex( sprintf("%.2X", $clientmsg->{i2caddress}) ),
  346. );
  347. # if (defined($clientmsg->{nbyte}) && defined($clientmsg->{reg}) && defined($clientmsg->{data}) && $clientmsg->{direction} eq "i2cblockwrite") { #blockweise beschreiben (Register)
  348. if ( defined($clientmsg->{reg}) && defined($clientmsg->{data}) && $clientmsg->{direction} eq "i2cwrite") { #blockweise beschreiben (Register)
  349. my @data = split(" ", $clientmsg->{data});
  350. my $dataref = \@data;
  351. $inh = $dev->writeBlockData( $clientmsg->{reg} , $dataref );
  352. my $wr = join(" ", @{$dataref});
  353. Log3 $hash, 5, "$hash->{NAME}: Block schreiben Register: " . sprintf("0x%.2X", $clientmsg->{reg}) . " Inhalt: " . $wr . " N: ". int(@data) ." Returnvar.: $inh";
  354. $status = "Ok" if $inh == 0;
  355. # } elsif (defined($clientmsg->{reg}) && defined($clientmsg->{data}) && $clientmsg->{direction} eq "i2cwrite") { #byteweise beschreiben (Register)
  356. } elsif (defined($clientmsg->{reg}) && defined($clientmsg->{data}) && $clientmsg->{direction} eq "i2cbytewrite") { #byteweise beschreiben (Register)
  357. my @data = split(" ", $clientmsg->{data});
  358. foreach (@data) {
  359. $inh = $dev->writeByteData($clientmsg->{reg},$_);
  360. Log3 $hash, 5, "$hash->{NAME}; Register ".sprintf("0x%.2X", $clientmsg->{reg})." schreiben - Inhalt: " .sprintf("0x%.2X",$_) . " Returnvar.: $inh";
  361. last if $inh != 0;
  362. $status = "Ok" if $inh == 0;
  363. }
  364. } elsif (defined($clientmsg->{data}) && ( $clientmsg->{direction} eq "i2cwrite" || $clientmsg->{direction} eq "i2cbytewrite" ) ) { #Byte(s) schreiben
  365. my @data = split(" ", $clientmsg->{data});
  366. foreach (@data) {
  367. $inh = $dev->writeByte($_);
  368. Log3 $hash, 5, "$hash->{NAME} Byte schreiben; Inh: " . $_ . " Returnvar.: $inh";
  369. last if $inh != 0;
  370. $status = "Ok" if $inh == 0;
  371. }
  372. } elsif (defined($clientmsg->{reg}) && ( $clientmsg->{direction} eq "i2cread" || $clientmsg->{direction} eq "i2cbyteread" ) ) { #byteweise lesen (Register)
  373. my $nbyte = defined($clientmsg->{nbyte}) ? $clientmsg->{nbyte} : 1;
  374. my $rmsg = "";
  375. for (my $n = 0; $n < $nbyte; $n++) {
  376. $inh = $dev->readByteData($clientmsg->{reg} + $n );
  377. Log3 $hash, 5, "$hash->{NAME}; Register ".sprintf("0x%.2X", $clientmsg->{reg} + $n )." lesen - Inhalt: ".sprintf("0x%.2X",$inh);
  378. last if ($inh < 0);
  379. #$rmsg .= sprintf("%.2X",$inh);
  380. $rmsg .= $inh;
  381. $rmsg .= " " if $n <= $nbyte;
  382. $status = "Ok" if ($n + 1) == $nbyte;
  383. }
  384. #@{$clientmsg->{received}} = split(" ", $rmsg) if($rmsg); #Daten als Array uebertragen
  385. $clientmsg->{received} = $rmsg if($rmsg); #Daten als Scalar uebertragen
  386. } elsif ($clientmsg->{direction} eq "i2cread"|| $clientmsg->{direction} eq "i2cbyteread") { #Byte lesen
  387. my $nbyte = defined($clientmsg->{nbyte}) ? $clientmsg->{nbyte} : 1;
  388. my $rmsg = "";
  389. for (my $n = 0; $n < $nbyte; $n++) {
  390. $inh = $dev->readByte();
  391. Log3 $hash, 5, "$hash->{NAME} Byte lesen; Returnvar.: $inh";
  392. last if ($inh < 0);
  393. $rmsg .= $inh;
  394. $rmsg .= " " if $n <= $nbyte;
  395. $status = "Ok" if ($n + 1) == $nbyte;
  396. }
  397. #@{$clientmsg->{received}} = split(" ", $rmsg) if($rmsg); #Daten als Array uebertragen
  398. $clientmsg->{received} = $rmsg if($rmsg); #Daten als Scalar uebertragen
  399. }
  400. $hash->{STATE} = $status;
  401. $hash->{ERRORCNT} = defined($hash->{ERRORCNT}) ? $hash->{ERRORCNT} += 1 : 1 if $status ne "Ok";
  402. $clientmsg->{$hash->{NAME} . "_" . "RAWMSG"} = $inh;
  403. return $status;
  404. }
  405. #####################
  406. sub RPII2C_HWACCESS_ioctl($$) {
  407. my ($hash, $clientmsg) = @_;
  408. my $status = "error";
  409. Log3 $hash, 5, "$hash->{NAME}: HWaccess I2CAddr: " . sprintf("0x%.2X", $clientmsg->{i2caddress});
  410. my ($fh, $msg) = undef;
  411. my $ankommen = "$hash->{NAME}: vom client empfangen";
  412. foreach my $av (keys %{$clientmsg}) { $ankommen .= "|" . $av . ": " . $clientmsg->{$av}; }
  413. Log3 $hash, 5, $ankommen;
  414. #Log3 $hash, 1, $ankommen if $clientmsg->{test} eq "local";
  415. my $i2caddr = hex(sprintf "%x", $clientmsg->{i2caddress});
  416. if ( sysopen(my $fh, $hash->{DeviceName}, O_RDWR) != 1) { #Datei oeffnen
  417. Log3 $hash, 3, "$hash->{NAME}: HWaccess sysopen failure: $!"
  418. } elsif( not defined( ioctl($fh,$I2C_SLAVE,$i2caddr) ) ) { #I2C Adresse per ioctl setzen
  419. Log3 $hash, 3, "$hash->{NAME}: HWaccess (0x".unpack( "H2",pack "C", $clientmsg->{i2caddress}).") ioctl failure: $!"
  420. # } elsif (defined($clientmsg->{nbyte}) && defined($clientmsg->{reg}) && defined($clientmsg->{data}) && $clientmsg->{direction} eq "i2cblockwrite") { #blockweise schreiben
  421. } elsif ( defined($clientmsg->{data}) && $clientmsg->{direction} eq "i2cwrite") { #blockweise schreiben
  422. my $data = defined($clientmsg->{reg}) ? chr($clientmsg->{reg}) : undef;
  423. foreach (split(" ", $clientmsg->{data})) {
  424. $data .= chr($_);
  425. }
  426. my $retval = syswrite($fh, $data, length($data));
  427. unless (defined($retval) && $retval == length($data)) {
  428. 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: $!";
  429. } else {
  430. $status = "Ok";
  431. 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)."|";
  432. }
  433. # } elsif (defined($clientmsg->{data}) && $clientmsg->{direction} eq "i2cwrite") { #byteweise schreiben
  434. } elsif (defined($clientmsg->{data}) && $clientmsg->{direction} eq "i2cbytewrite") { #byteweise schreiben
  435. my $reg = undef;
  436. $reg = $clientmsg->{reg} if (defined($clientmsg->{reg}));
  437. $status = "Ok";
  438. foreach (split(" ", $clientmsg->{data})) {
  439. my $data = (defined($reg) ? chr($reg++) : "") . chr($_);
  440. my $retval = syswrite($fh, $data, length($data));
  441. #Log3 $hash, 1, "retval= $retval" if $clientmsg->{test} eq "local";
  442. unless (defined($retval) && $retval == length($data)) {
  443. 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: $!";
  444. $status = "error";
  445. last;
  446. }
  447. 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);
  448. #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";
  449. }
  450. # } elsif ($clientmsg->{direction} eq "i2cread") { #byteweise lesen
  451. } elsif ($clientmsg->{direction} eq "i2cbyteread") { #byteweise lesen
  452. my $nbyte = defined($clientmsg->{nbyte}) ? $clientmsg->{nbyte} : 1;
  453. my $rmsg = "";
  454. foreach (my $n = 0; $n < $nbyte; $n++) {
  455. if ( defined($clientmsg->{reg}) ) {
  456. Log3 $hash, 5, "$hash->{NAME}: HWaccess byteweise lesen setze Registerpointer auf " . ($clientmsg->{reg} + $n);
  457. my $retval = syswrite($fh, chr($clientmsg->{reg} + $n), 1);
  458. unless (defined($retval) && $retval == 1) {
  459. 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 $!;
  460. last;
  461. }
  462. }
  463. if (defined($clientmsg->{usleep})) {
  464. usleep($clientmsg->{usleep});
  465. }
  466. my $buf = undef;
  467. my $retval = sysread($fh, $buf, 1);
  468. unless (defined($retval) && $retval == 1) {
  469. 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 $!;
  470. last;
  471. }
  472. $rmsg .= ord($buf);
  473. $rmsg .= " " if $n <= $nbyte;
  474. $status = "Ok" if ($n + 1) == $nbyte;
  475. }
  476. $clientmsg->{received} = $rmsg if($rmsg); #Daten als Scalar uebertragen
  477. # } elsif ($clientmsg->{direction} eq "i2cblockread") { #blockweise lesen
  478. } elsif ($clientmsg->{direction} eq "i2cread") { #blockweise lesen
  479. my $nbyte = defined($clientmsg->{nbyte}) ? $clientmsg->{nbyte} : 1;
  480. #Log3 $hash, 1, "test Blockweise lese menge: |$nbyte|, reg: |". $clientmsg->{reg} ."|";
  481. my $rmsg = "";
  482. if ( defined($clientmsg->{reg}) ) {
  483. Log3 $hash, 4, "$hash->{NAME}: HWaccess blockweise lesen setze Registerpointer auf " . ($clientmsg->{reg});
  484. my $retval = syswrite($fh, chr($clientmsg->{reg}), 1);
  485. unless (defined($retval) && $retval == 1) {
  486. 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 $!;
  487. last;
  488. }
  489. }
  490. if (defined($clientmsg->{usleep})) {
  491. usleep($clientmsg->{usleep});
  492. }
  493. my $buf = undef;
  494. my $retval = sysread($fh, $buf, $nbyte);
  495. #Log3 $hash, 1, "test Blockweise lesen menge: |$nbyte|, return: |$retval|, inh: |$buf|";
  496. unless (defined($retval) && $retval == $nbyte) {
  497. 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 $!;
  498. last;
  499. } else {
  500. $status = "Ok"
  501. }
  502. #Log3 $hash, 1, "test Blockweise lesen menge: |$nbyte|, inh: $buf";
  503. $rmsg = $buf;
  504. $rmsg =~ s/(.|\n)/sprintf("%u ",ord($1))/eg;
  505. #Log3 $hash, 1, "test Blockweise lesen ergebnis: |$rmsg|";
  506. $clientmsg->{received} = $rmsg if($rmsg); #Daten als Scalar uebertragen
  507. }
  508. $hash->{STATE} = $status;
  509. $hash->{ERRORCNT} = defined($hash->{ERRORCNT}) ? $hash->{ERRORCNT} += 1 : 1 if $status ne "Ok";
  510. #$clientmsg->{$hash->{NAME} . "_" . "RAWMSG"} = $inh;
  511. return $status;
  512. }
  513. =pod
  514. =item device
  515. =item summary accesses I2C interface via sysfs on linux
  516. =item summary_DE Zugriff auf das I2C-Interface &uuml;ber sysfs auf Linux Systemen
  517. =begin html
  518. <a name="RPII2C"></a>
  519. <h3>RPII2C</h3>
  520. (en | <a href="commandref_DE.html#RPII2C">de</a>)
  521. <ul>
  522. <a name="RPII2C"></a>
  523. Provides access to Raspberry Pi's I2C interfaces for some logical modules and also directly.<br>
  524. This modul will basically work on every linux system that provides <code>/dev/i2c-x</code>.<br><br>
  525. <b>preliminary:</b><br>
  526. <ul>
  527. <li>
  528. load I2C kernel modules (choose <b>one</b> of the following options):<br>
  529. <ul>
  530. <li>
  531. open /etc/modules<br>
  532. <ul><code>sudo nano /etc/modules</code></ul><br>
  533. add these lines<br>
  534. <ul><code>
  535. i2c-dev<br>
  536. i2c-bcm2708<br>
  537. </code></ul>
  538. </li>
  539. <li>
  540. Since Kernel 3.18.x on raspberry pi and maybe on other boards too, device tree support was implemented and enabled by default.
  541. To enable I2C support just add
  542. <ul><code>device_tree_param=i2c0=on,i2c1=on</code></ul> to /boot/config.txt
  543. You can also enable just one of the I2C. In this case remove the unwantet one from the line.
  544. </li>
  545. <li>
  546. 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
  547. </li>
  548. reboot
  549. </ul>
  550. </li><br>
  551. <li>Choose <b>only one</b> of the three follwing methodes do grant access to <code>/dev/i2c-*</code> for FHEM user:
  552. <ul>
  553. <li>
  554. <code>sudo apt-get install i2c-tools<br>
  555. sudo adduser fhem i2c<br>
  556. sudo reboot</code><br>
  557. </li><br>
  558. <li>
  559. 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>
  560. <code>
  561. sudo chown fhem /dev/i2c-*<br>
  562. sudo chgrp dialout /dev/i2c-*<br>
  563. sudo chmod +t /dev/i2c-*<br>
  564. sudo chmod 660 /dev/i2c-*<br>
  565. </code>
  566. </li><br>
  567. <li>
  568. 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>
  569. WiringPi installation is described here: <a href="#RPI_GPIO">RPI_GPIO.</a><br>
  570. gpio utility will be automaticly used, if installed.<br>
  571. Important: to use I2C-0 at P5 connector you must use attribute <code>swap_i2c0</code>.<br>
  572. </li>
  573. </ul>
  574. </li><br>
  575. <li>
  576. <b>Optional</b>: access via IOCTL will be used (RECOMMENDED) if Device::SMBus is not present.<br>
  577. To access the I2C-Bus via the Device::SMBus module, following steps are necessary:<br>
  578. <ul><code>sudo apt-get install libmoose-perl<br>
  579. sudo cpan Device::SMBus</code></ul><br>
  580. </li>
  581. <li>
  582. <b>For Raspbian users only</b><br>
  583. 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>
  584. <ul><code>bcm2708.vc_i2c_override=1</code></ul><br>
  585. </li>
  586. </ul>
  587. <a name="RPII2CDefine"></a><br>
  588. <b>Define</b>
  589. <ul>
  590. <code>define &lt;name&gt; RPII2C &lt;I2C Bus Number&gt;</code><br>
  591. where <code>&lt;I2C Bus Number&gt;</code> is the number of the I2C bus that should be used (0 or 1)<br><br>
  592. </ul>
  593. <a name="RPII2CSet"></a>
  594. <b>Set</b>
  595. <ul>
  596. <li>
  597. Write one byte (or more bytes sequentially) directly to an I2C device (for devices that have only one register to write):<br>
  598. <code>set &lt;name&gt; writeByte &lt;I2C Address&gt; &lt;value&gt;</code><br><br>
  599. </li>
  600. <li>
  601. Write n-bytes to an register range (as an series of single register write operations), beginning at the specified register:<br>
  602. <code>set &lt;name&gt; writeByteReg &lt;I2C Address&gt; &lt;Register Address&gt; &lt;value&gt; [&lt;value&gt; [..]]</code><br><br>
  603. </li>
  604. <li>
  605. Write n-bytes directly to an I2C device (as an block write operation):<br>
  606. <code>set &lt;name&gt; writeBlock &lt;I2C Address&gt; &lt;Register Address&gt; &lt;value&gt; [&lt;value&gt; [..]]</code><br><br>
  607. </li>
  608. <li>
  609. Write n-bytes to an register range (as an block write operation), beginning at the specified register:<br>
  610. <code>set &lt;name&gt; writeBlockReg &lt;I2C Address&gt; &lt;Register Address&gt; &lt;value&gt; [&lt;value&gt; [..]]</code><br><br>
  611. </li><br>
  612. Examples:
  613. <ul>
  614. Write 0xAA to device with I2C address 0x60<br>
  615. <code>set test1 writeByte 60 AA</code><br>
  616. Write 0xAA to register 0x01 of device with I2C address 0x6E<br>
  617. <code>set test1 writeByteReg 6E 01 AA</code><br>
  618. Write 0xAA to register 0x01 of device with I2C address 0x6E, after it write 0x55 to 0x02 as two separate commands<br>
  619. <code>set test1 writeByteReg 6E 01 AA 55</code><br>
  620. 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>
  621. <code>set test1 writeBlock 60 03 A4 00 DA</code><br>
  622. </ul><br>
  623. </ul>
  624. <a name="RPII2CGet"></a>
  625. <b>Get</b>
  626. <ul>
  627. <li>
  628. Gets value of I2C device's registers:<br>
  629. <code>get &lt;name&gt; read &lt;I2C Address&gt; [&lt;Register Address&gt; [&lt;number of registers&gt;]]</code><br><br>
  630. </li>
  631. <li>
  632. Gets value of I2C device in blockwise mode:<br>
  633. <code>get &lt;name&gt; readblock &lt;I2C Address&gt; [&lt;number of registers&gt;]</code><br><br>
  634. </li>
  635. <li>
  636. Gets value of I2C device's registers in blockwise mode:<br>
  637. <code>get &lt;name&gt; readblockreg &lt;I2C Address&gt; &lt;Register Address&gt; [&lt;number of registers&gt;]</code><br><br>
  638. </li><br>
  639. Examples:
  640. <ul>
  641. Reads byte from device with I2C address 0x60<br>
  642. <code>get test1 read 60</code><br>
  643. Reads register 0x01 of device with I2C address 0x6E.<br>
  644. <code>get test1 read 6E 01 AA 55</code><br>
  645. Reads register 0x03 to 0x06 of device with I2C address 0x60.<br>
  646. <code>get test1 read 60 03 4</code><br>
  647. </ul><br>
  648. </ul><br>
  649. <a name="RPII2CAttr"></a>
  650. <b>Attributes</b>
  651. <ul>
  652. <li>swap_i2c0<br>
  653. Swap Raspberry Pi's I2C-0 from J5 to P5 rev. B<br>
  654. This attribute is for Raspberry Pi only and needs gpio utility from <a href="http://wiringpi.com/download-and-install/">WiringPi</a> library.<br>
  655. Default: none, valid values: on, off<br><br>
  656. </li>
  657. <li>useHWLib<br>
  658. Change hardware access method.<br>
  659. Attribute exists only if both access methods are usable<br>
  660. Default: IOCTL, valid values: IOCTL, SMBus<br><br>
  661. </li>
  662. <li><a href="#ignore">ignore</a></li>
  663. <li><a href="#do_not_notify">do_not_notify</a></li>
  664. <li><a href="#showtime">showtime</a></li>
  665. </ul>
  666. <br>
  667. </ul>
  668. =end html
  669. =begin html_DE
  670. <a name="RPII2C"></a>
  671. <h3>RPII2C</h3>
  672. (<a href="commandref.html#RPII2C">en</a> | de)
  673. <ul>
  674. <a name="RPII2C"></a>
  675. Erm&ouml;glicht den Zugriff auf die I2C Schnittstellen des Raspberry Pi, BBB, Cubie &uuml;ber logische Module. Register von I2C IC's k&ouml;nnen auch direkt gelesen und geschrieben werden.<br><br>
  676. Dieses Modul funktioniert gruns&auml;tzlich auf allen Linux Systemen, die <code>/dev/i2c-x</code> bereitstellen.<br><br>
  677. <b>Vorbereitung:</b><br>
  678. <ul>
  679. <li>
  680. I2C Kernelmodule laden (chose <b>one</b> of the following options):<br>
  681. <ul>
  682. <li>
  683. I2C Kernelmodule laden:<br>
  684. modules Datei &ouml;ffnen<br>
  685. <ul><code>sudo nano /etc/modules</code></ul><br>
  686. folgendes einf&uuml;gen<br>
  687. <ul><code>
  688. i2c-dev<br>
  689. i2c-bcm2708<br>
  690. </code></ul>
  691. </li>
  692. <li>
  693. Seit Kernel 3.18.x auf dem Raspberry Pi und evtl. auch auf anderen Systemen ist der "Device tree support" implementiert und standardm&auml;&szlig;ig aktiviert.
  694. Um I2C Unterst&uuml;tzung zu aktivieren mu&szlig;
  695. <ul><code>device_tree_param=i2c0=on,i2c1=on</code></ul> zur /boot/config.txt hinzu gef&uuml;gt werden.
  696. Wenn nur einer der Busse genutzt wird, kann der andere einfach aus der Zeile entfernt werden.
  697. </li>
  698. <li>
  699. Bei Raspbian Images seit 2015 kann der I2C Bus einfach &uuml;ber <code>sudo raspi-config</code> aktiviert werden. Die Parameter werden automatisch in die /boot/config.txt eingetragen.
  700. </li>
  701. Neustart
  702. </ul>
  703. </li><br>
  704. <li><b>Eine</b> der folgenden drei M&ouml;glichkeiten w&auml;hlen um dem FHEM User Zugriff auf <code>/dev/i2c-*</code> zu geben:
  705. <ul>
  706. <li>
  707. <code>
  708. sudo apt-get install i2c-tools<br>
  709. sudo adduser fhem i2c</code><br>
  710. </li><br>
  711. <li>
  712. 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&uuml;gen:<br>
  713. <code>
  714. sudo chown fhem /dev/i2c-*<br>
  715. sudo chgrp dialout /dev/i2c-*<br>
  716. sudo chmod +t /dev/i2c-*<br>
  717. sudo chmod 660 /dev/i2c-*<br>
  718. </code>
  719. </li><br>
  720. <li>
  721. F&uumlr 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>
  722. WiringPi Installation ist hier beschrieben: <a href="#RPI_GPIO">RPI_GPIO</a><br>
  723. Das gpio Utility wird, wenn vorhanden, automatisch verwendet<br>
  724. Wichtig: um den I2C-0 am P5 Stecker des Raspberry nutzen zu k&ouml;nnen muss das Attribut <code>swap_i2c0</code> verwendet werden.<br>
  725. </li>
  726. </ul>
  727. </li><br>
  728. <li>
  729. <b>Optional</b>: Hardwarezugriff via IOCTL wird standardm&auml;&szlig;ig genutzt (EMPFOHLEN), wenn Device::SMBus nicht installiert ist<br>
  730. Soll der Hardwarezugriff &uuml;ber das Perl Modul Device::SMBus erfolgen sind diese Schritte notwendig:<br>
  731. <ul><code>sudo apt-get install libmoose-perl<br>
  732. sudo cpan Device::SMBus</code></ul><br>
  733. </li>
  734. <li>
  735. <b>Nur f&uuml;r Raspbian Nutzer</b><br>
  736. 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&uuml;tzen, muss folgende Zeile in die <code>/boot/cmdline.txt</code> eingef&uuml;gt werden:<br>
  737. <ul><code>bcm2708.vc_i2c_override=1</code></ul><br>
  738. </li>
  739. </ul>
  740. <a name="RPII2CDefine"></a><br>
  741. <b>Define</b>
  742. <ul>
  743. <code>define &lt;name&gt; RPII2C &lt;I2C Bus Number&gt;</code><br>
  744. Die <code>&lt;I2C Bus Number&gt;</code> ist die Nummer des I2C Bus an den die I2C IC's angeschlossen werden<br><br>
  745. </ul>
  746. <a name="RPII2CSet"></a>
  747. <b>Set</b>
  748. <ul>
  749. <li>
  750. 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>
  751. <code>set &lt;name&gt; writeByte &lt;I2C Address&gt; &lt;value&gt;</code><br><br>
  752. </li>
  753. <li>
  754. Schreibe n-bytes auf einen Registerbereich (als Folge von Einzelbefehlen), beginnend mit dem angegebenen Register:<br>
  755. <code>set &lt;name&gt; writeByteReg &lt;I2C Address&gt; &lt;Register Address&gt; &lt;value&gt; [&lt;value&gt; [..]]</code><br><br>
  756. </li>
  757. <li>
  758. Schreibe n-bytes auf ein I2C device (als Blockoperation):<br>
  759. <code>set &lt;name&gt; writeBlock &lt;I2C Address&gt; &lt;value&gt; [&lt;value&gt; [..]]</code><br><br>
  760. </li>
  761. <li>
  762. Schreibe n-bytes auf einen Registerbereich (als Blockoperation), beginnend mit dem angegebenen Register:<br>
  763. <code>set &lt;name&gt; writeBlockReg &lt;I2C Address&gt; &lt;Register Address&gt; &lt;value&gt; [&lt;value&gt; [..]]</code><br><br>
  764. </li><br>
  765. Beispiele:
  766. <ul>
  767. Schreibe 0xAA zu Modul mit I2C Addresse 0x60<br>
  768. <code>set test1 writeByte 60 AA</code><br>
  769. Schreibe 0xAA zu Register 0x01 des Moduls mit der I2C Adresse 0x6E<br>
  770. <code>set test1 writeByteReg 6E 01 AA</code><br>
  771. Schreibe 0xAA zu Register 0x01 des Moduls mit der I2C Adresse 0x6E, schreibe danach 0x55 in das Register 0x02 als einzelne Befehle<br>
  772. <code>set test1 writeByteReg 6E 01 AA 55</code><br>
  773. 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>
  774. <code>set test1 writeBlockReg 60 03 A4 00 DA</code><br>
  775. </ul><br>
  776. </ul>
  777. <a name="RPII2CGet"></a>
  778. <b>Get</b>
  779. <ul>
  780. <li>
  781. Auslesen der Registerinhalte des I2C Moduls:<br>
  782. <code>get &lt;name&gt; read &lt;I2C Address&gt; [&lt;Register Address&gt; [&lt;number of registers&gt;]]</code><br><br>
  783. </li>
  784. <li>
  785. Blockweises Auslesen des I2C Moduls (ohne separate Register):<br>
  786. <code>get &lt;name&gt; readblock &lt;I2C Address&gt; [&lt;number of registers&gt;]</code><br><br>
  787. </li>
  788. <li>
  789. Blockweises Auslesen der Registerinhalte des I2C Moduls:<br>
  790. <code>get &lt;name&gt; readblockreg &lt;I2C Address&gt; &lt;Register Address&gt; [&lt;number of registers&gt;]</code><br><br>
  791. </li><br>
  792. Beispiele:
  793. <ul>
  794. Lese Byte vom Modul mit der I2C Adresse 0x60<br>
  795. <code>get test1 read 60</code><br>
  796. Lese den Inhalt des Registers 0x01 vom Modul mit der I2C Adresse 0x6E.<br>
  797. <code>get test1 read 6E 01 AA 55</code><br>
  798. Lese den Inhalt des Registerbereichs 0x03 bis 0x06 vom Modul mit der I2C Adresse 0x60.<br>
  799. <code>get test1 read 60 03 4</code><br>
  800. </ul><br>
  801. </ul><br>
  802. <a name="RPII2CAttr"></a>
  803. <b>Attribute</b>
  804. <ul>
  805. <li>swap_i2c0<br>
  806. Umschalten von I2C-0 des Raspberry Pi Rev. B von J5 auf P5<br>
  807. Dieses Attribut ist nur f&uuml;r das Raspberry Pi vorgesehen und ben&ouml;tigt das gpio utility wie unter dem Punkt Vorbereitung beschrieben.<br>
  808. Standard: keiner, g&uuml;ltige Werte: on, off<br><br>
  809. </li>
  810. <li>useHWLib<br>
  811. &Auml;ndern der Methode des Hardwarezugriffs.<br>
  812. Dieses Attribut existiert nur, wenn beide Zugriffsmethoden verf&uuml;gbar sind<br>
  813. Standard: IOCTL, g&uuml;ltige Werte: IOCTL, SMBus<br><br>
  814. </li>
  815. <li><a href="#ignore">ignore</a></li>
  816. <li><a href="#do_not_notify">do_not_notify</a></li>
  817. <li><a href="#showtime">showtime</a></li>
  818. </ul>
  819. <br>
  820. </ul>
  821. =end html_DE
  822. 1;