File Coverage

blib/lib/HiPi/Interface/PCA9544.pm
Criterion Covered Total %
statement 18 50 36.0
branch 0 24 0.0
condition n/a
subroutine 6 11 54.5
pod 0 5 0.0
total 24 90 26.6


line stmt bran cond sub pod time code
1             #########################################################################################
2             # Package HiPi::Interface::PCA9544
3             # Description : Control NXP PCA9544A & Philips PCA9544 4 channel I2C MUX
4             # Copyright : Copyright (c) 2018 Mark Dootson
5             # License : This is free software; you can redistribute it and/or modify it under
6             # the same terms as the Perl 5 programming language system itself.
7             #########################################################################################
8              
9             package HiPi::Interface::PCA9544;
10              
11             #########################################################################################
12              
13 1     1   1008 use strict;
  1         3  
  1         29  
14 1     1   6 use warnings;
  1         2  
  1         27  
15 1     1   5 use parent qw( HiPi::Interface );
  1         2  
  1         6  
16 1     1   58 use HiPi qw( :i2c :rpi );
  1         3  
  1         364  
17 1     1   9 use Carp;
  1         2  
  1         100  
18              
19             __PACKAGE__->create_ro_accessors( qw(
20             devicename
21             backend
22             ) );
23              
24             our $VERSION ='0.81';
25              
26             use constant {
27 1         748 CHANNEL_BIT => 0x4,
28             CHANNEL_0 => 0x4,
29             CHANNEL_1 => 0x5,
30             CHANNEL_2 => 0x6,
31             CHANNEL_3 => 0x7,
32             CHANNEL_NONE => 0x0,
33             CHANNEL_MASK => 0x7,
34             INTERRUPT_0 => 0x10,
35             INTERRUPT_1 => 0x20,
36             INTERRUPT_2 => 0x40,
37             INTERRUPT_3 => 0x80,
38 1     1   8 };
  1         2  
39              
40             sub new {
41 0     0 0   my ($class, %userparams) = @_;
42            
43 0           my $pi = HiPi::RaspberryPi->new();
44            
45 0 0         my %params = (
46             devicename => ( $pi->board_type == RPI_BOARD_TYPE_1 ) ? '/dev/i2c-0' : '/dev/i2c-1',
47             address => 0x70,
48             device => undef,
49             backend => 'i2c',
50             );
51            
52             # get user params
53 0           foreach my $key( keys (%userparams) ) {
54 0           $params{$key} = $userparams{$key};
55             }
56            
57 0 0         unless( defined($params{device}) ) {
58 0 0         if ( $params{backend} eq 'bcm2835' ) {
59 0           require HiPi::BCM2835::I2C;
60             $params{device} = HiPi::BCM2835::I2C->new(
61             address => $params{address},
62 0 0         peripheral => ( $params{devicename} eq '/dev/i2c-0' ) ? HiPi::BCM2835::I2C::BB_I2C_PERI_0() : HiPi::BCM2835::I2C::BB_I2C_PERI_1(),
63             );
64             } else {
65 0           require HiPi::Device::I2C;
66             $params{device} = HiPi::Device::I2C->new(
67             devicename => $params{devicename},
68             address => $params{address},
69 0           busmode => 'i2c', # needs read without write
70             );
71             }
72             }
73            
74 0           my $self = $class->SUPER::new(%params);
75            
76 0           return $self;
77             }
78              
79             sub set_channel {
80 0     0 0   my($self, $channel) = @_;
81 0 0         if(!defined($channel)) {
    0          
82 0           $self->write_control_register( CHANNEL_NONE );
83             } elsif( $channel =~ /^0|1|2|3$/ ) {
84 0           $self->write_control_register( $channel + CHANNEL_BIT );
85             } else {
86 0           warn 'invalid channel requested';
87             }
88             }
89              
90             sub get_status {
91 0     0 0   my $self = shift;
92 0           my $register = $self->read_control_register();
93 0           my $channel = undef;
94 0           my $regbits = $register & CHANNEL_MASK;
95            
96 0 0         if( $regbits & CHANNEL_BIT ) {
97 0           $channel = $regbits - CHANNEL_BIT;
98             }
99            
100 0 0         return $channel unless( wantarray );
101            
102 0 0         my @interrupts = (
    0          
    0          
    0          
103             ( $register & INTERRUPT_0 ) ? 1 : 0,
104             ( $register & INTERRUPT_1 ) ? 1 : 0,
105             ( $register & INTERRUPT_2 ) ? 1 : 0,
106             ( $register & INTERRUPT_3 ) ? 1 : 0,
107             );
108            
109 0           return ( $channel , @interrupts );
110             }
111              
112             sub read_control_register {
113 0     0 0   my( $self ) = @_;
114 0           my @bytes = $self->device->bus_read( undef, 1 );
115 0           return $bytes[0];
116             }
117              
118             sub write_control_register {
119 0     0 0   my( $self , $regbyte) = @_;
120 0           $self->device->bus_write( $regbyte );
121             }
122              
123             1;
124              
125             __END__