#########################################################################################
# Package HiPi::Interface::Common::HD44780
# Description : Control a LCD based on HD44780
# Copyright : Copyright (c) 2013-2017 Mark Dootson
# License : This is free software; you can redistribute it and/or modify it under
# the same terms as the Perl 5 programming language system itself.
#########################################################################################
package HiPi::Interface::Common::HD44780;
#########################################################################################
use strict;
use warnings;
use parent qw( HiPi::Interface );
use Carp;
use HiPi qw( :lcd );
use Time::HiRes;
our $VERSION ='0.69';
__PACKAGE__->create_accessors( qw(
width lines backlightcontrol positionmap devicename serialbuffermode
) );
sub new {
my ($class, %userparams ) = @_;
my %params = (
width => undef,
lines => undef,
backlightcontrol => 0,
device => undef,
positionmap => undef,
);
# get user params
foreach my $key( keys (%userparams) ) {
$params{$key} = $userparams{$key};
}
croak('A derived class must provide a device') unless(defined($params{device}));
unless( $params{positionmap} ) {
# setup default position map
unless( $params{width} =~ /^(16|20)$/ && $params{lines} =~ /^(2|4)$/) {
croak('HiPi::Interface::Common::HD44780 only supports default LCD types 16x2, 16x4, 20x2, 20x4' );
}
my (@pmap, @line1, @line2, @line3, @line4, @buffers);
if( $params{width} == 16 && $params{serialbuffermode} ) {
@line1 = (0..15);
@line2 = (64..79);
@line3 = (16..31);
@line4 = (80..95);
} else {
@line1 = (0..19);
@line2 = (64..83);
@line3 = (20..39);
@line4 = (84..103);
}
if( $params{lines} == 2 ) {
@pmap = ( @line1, @line2 );
} elsif( $params{lines} == 4 ) {
@pmap = ( @line1, @line2, @line3, @line4 );
}
$params{positionmap} = \@pmap;
}
my $self = $class->SUPER::new(%params);
$self->update_geometry; # will set cols / lines to controller
return $self;
}
sub enable {
my($self, $enable) = @_;
$enable = 1 unless defined($enable);
my $command = ( $enable ) ? HD44780_DISPLAY_ON : HD44780_DISPLAY_OFF;
$self->send_command( $command ) ;
}
sub set_cursor_position {
my($self, $col, $row) = @_;
my $pos = $col + ( $row * $self->width );
$self->send_command( HD44780_CURSOR_POSITION + $self->positionmap->[$pos] );
}
sub move_cursor_left {
$_[0]->send_command( HD44780_SHIFT_CURSOR_LEFT );
}
sub move_cursor_right {
$_[0]->send_command( HD44780_SHIFT_CURSOR_RIGHT );
}
sub home { $_[0]->send_command( HD44780_HOME_UNSHIFT ); }
sub clear { $_[0]->send_command( HD44780_CLEAR_DISPLAY ); Time::HiRes::usleep(2000); }
sub set_cursor_mode { $_[0]->send_command( $_[1] ); }
sub backlight { croak('backlight must be overriden in derived class'); }
sub send_text { croak('send_text must be overriden in derived class'); }
sub send_command { croak('send_command must be overriden in derived class'); }
sub update_baudrate { croak('update_baudrate must be overriden in derived class'); }
sub update_geometry { croak('update_geometry must be overriden in derived class'); }
1;
__END__