2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-21 07:56:03 +00:00

I2C_LCD: add attribute pinMapping

Merge branch 'I2C'

git-svn-id: https://svn.fhem.de/fhem/trunk@5492 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
ntruchsess 2014-04-08 23:01:18 +00:00
parent baf02659c1
commit 3de34d0735
2 changed files with 88 additions and 22 deletions

View File

@ -66,6 +66,13 @@ I2C_LCD_Define($$)
my @a = split("[ \t][ \t]*", $def);
$hash->{STATE}="defined";
my @keyvalue = ();
while (my ($key, $value) = each %mapping) {
push @keyvalue,"$key=$value";
};
$main::attr{$a[0]}{"pinMapping"} = join (',',sort @keyvalue);
$hash->{mapping} = \%mapping;
if ($main::init_done) {
eval {
@ -73,12 +80,7 @@ I2C_LCD_Define($$)
};
return I2C_LCD_Catch($@) if $@;
}
my @keyvalue = ();
while (my ($key, $value) = each %mapping) {
push @keyvalue,"$key=$value";
};
$main::attr{$a[0]}{"pinMapping"} = join (',',sort @keyvalue);;
return undef;
}
@ -92,14 +94,17 @@ I2C_LCD_Init($$)
$hash->{sizex} = shift @$args;
$hash->{sizey} = shift @$args;
$hash->{I2C_Address} = shift @$args if (@$args);
if (defined (my $address = shift @$args)) {
$hash->{I2C_Address} = $address =~ /^0.*$/ ? oct($address) : $address;
}
my $name = $hash->{NAME};
if (defined $hash->{I2C_Address}) {
eval {
main::AssignIoPort($hash,AttrVal($hash->{NAME},"IODev",undef));
require LiquidCrystal_I2C;
my $lcd = LiquidCrystal_I2C->new($hash->{I2C_Address},$hash->{sizex},$hash->{sizey},\%mapping);
require LiquidCrystal;
my $lcd = LiquidCrystal->new($hash->{sizex},$hash->{sizey});
$lcd->setMapping($hash->{mapping});
$lcd->attach(I2C_LCD_IO->new($hash));
$lcd->init();
$hash->{lcd} = $lcd;
@ -139,13 +144,16 @@ I2C_LCD_Attr($$$$) {
last;
};
$attribute eq "pinMapping" and do {
my %newMapping = ();
foreach my $keyvalue (split (/,/,$value)) {
my ($key,$value) = split (/=/,$keyvalue);
#Log3 ($name,5,"pinMapping, token: $key=$value, current mapping: $mapping{$key}");
die "unknown token $key in attribute pinMapping, valid tokens are ".join (',',keys %mapping) unless (defined $mapping{$key});
die "undefined or invalid value for token $key in attribute pinMapping, valid LED-Pins are ".join (',',@LEDPINS) unless $value and grep (/$value/,@LEDPINS);
$mapping{$key} = $value;
$newMapping{$key} = $value;
}
$hash->{mapping} = \%newMapping;
I2C_LCD_Init($hash,split (' ',$hash->{DEF})) if ($main::init_done);
last;
};
$main::attr{$name}{$attribute}=$value;
@ -352,12 +360,12 @@ sub new {
}, $class;
}
sub i2c_write {
my ( $self, $address, @data ) = @_;
sub write {
my ( $self, @data ) = @_;
my $hash = $self->{hash};
if (defined (my $iodev = $hash->{IODev})) {
main::CallFn($iodev->{NAME}, "I2CWrtFn", $iodev, {
i2caddress => $address,
i2caddress => $hash->{I2C_Address},
direction => "i2cwrite",
data => join (' ',@data)
});

View File

@ -1,3 +1,11 @@
# LiquidCrystal.pm
#
# Perl-library to drive LCD-displays controlled by Hitachi HD44780 LCD controller
#
# Copyright (C) 2013/2014 Norbert Truchsess (norbert.truchsess@t-online.de)
#
# based on LiquidCrystal.cpp as of:
#
# www.DFRobot.com
# last updated on 21/12/2011
# Tim Starling Fix the reset bug (Thanks Tim)
@ -5,7 +13,7 @@
# Support Forum: http://www.dfrobot.com/forum/
# Compatible with the Arduino IDE 1.0
# Library version:1.1
#
# When the display powers up, it is configured as follows:
#
# 1. Display clear
@ -25,7 +33,7 @@
# can't assume that its in that state when a sketch starts (and the
# LiquidCrystal constructor is called).
package LiquidCrystal_I2C;
package LiquidCrystal;
use warnings;
use strict;
@ -76,6 +84,17 @@ use constant En => 0b00000100; # Enable bit
use constant Rw => 0b00000010; # Read / Write bit
use constant Rs => 0b00000001; # Register select bit
our %mapping_bits = (
RS => 0,
RW => 1,
E => 2,
LED => 3,
D4 => 4,
D5 => 5,
D6 => 6,
D7 => 7,
);
sub print($$) {
my ($self,$c) = @_;
my @buf = unpack "c*",$c;
@ -90,14 +109,45 @@ sub write($$) {
return 0;
}
sub new($$$$) {
my ( $class, $lcd_Addr, $lcd_cols, $lcd_rows ) = @_;
return bless {
Addr => $lcd_Addr,
sub new($$$$@) {
my ( $class, $lcd_cols, $lcd_rows ) = @_;
my $lcd = bless {
cols => $lcd_cols,
rows => $lcd_rows,
backlightval => LCD_NOBACKLIGHT,
}, $class;
$lcd->setMapping();
return $lcd;
}
# $lcd_mapping = {
# 'P0' => 'RS',
# 'P1' => 'RW',
# 'P2' => 'E',
# 'P3' => 'LED',
# 'P4' => 'D4',
# 'P5' => 'D5',
# 'P6' => 'D6',
# 'P7' => 'D7',
#};
sub setMapping(@) {
my ( $self, $lcd_mapping ) = @_;
my %mapping;
if ( defined $lcd_mapping ) {
while (my ($key, $value) = each %$lcd_mapping) {
die "illegal value for MAPPING: $value, must be one of RS,RW,E,LED,D4,D5,D6,D7" unless grep {$value eq $_} keys %mapping_bits;
die "illegal value for PIN: $key, must be one of P0..P7" unless $key =~ /^P([\d])$/;
$mapping{0x01 << $mapping_bits{$value}} = 0x01 << $1;
}
} else {
foreach my $i (0..7) {
$mapping{0x01 << $i} = 0x01 << $i;
}
}
$self->{mapping} = \%mapping;
}
sub init($) {
@ -107,7 +157,7 @@ sub init($) {
sub attach($$) {
my ($self,$dev) = @_;
$self->{I2CDevice} = $dev;
$self->{io} = $dev;
}
sub init_priv($) {
@ -359,8 +409,16 @@ sub write4bits($$) {
sub expanderWrite($$) {
my ( $self, $data ) = @_;
$self->{I2CDevice}->i2c_write($self->{Addr},($data) | $self->{backlightval});
$data |= $self->{backlightval};
my $mapped = 0;
while (my ($orig, $remapped) = each %{$self->{mapping}}) {
$mapped |= $data & $orig ? $remapped : 0;
}
$self->{io}->write($mapped);
}
sub pulseEnable($$) {