File Coverage

blib/lib/HiPi/Interface/MCP3ADC.pm
Criterion Covered Total %
statement 18 50 36.0
branch 0 14 0.0
condition 0 8 0.0
subroutine 6 11 54.5
pod 0 5 0.0
total 24 88 27.2


line stmt bran cond sub pod time code
1             #########################################################################################
2             # Package HiPi::Interface::MCP3ADC
3             # Description : Control MCP3xxx Analog 2 Digital ICs
4             # Copyright : Copyright (c) 2013-2017 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::MCP3ADC;
10              
11             #########################################################################################
12              
13 1     1   1001 use strict;
  1         3  
  1         30  
14 1     1   10 use warnings;
  1         2  
  1         32  
15 1     1   5 use parent qw( HiPi::Interface );
  1         2  
  1         5  
16 1     1   52 use Carp;
  1         2  
  1         64  
17 1     1   10 use HiPi qw( :spi :mcp3adc );
  1         2  
  1         397  
18 1     1   9 use HiPi::Device::SPI;
  1         4  
  1         654  
19              
20             __PACKAGE__->create_ro_accessors( qw( devicename hsb_mask max_channel ic devbits ) );
21              
22             our $VERSION ='0.81';
23              
24             sub new {
25 0     0 0   my( $class, %userparams ) = @_;
26            
27 0           my %params = (
28             devicename => '/dev/spidev0.0',
29             speed => SPI_SPEED_MHZ_1,
30             bitsperword => 8,
31             delay => 0,
32             device => undef,
33             ic => MCP3008,
34             );
35            
36 0           foreach my $key (sort keys(%userparams)) {
37 0           $params{$key} = $userparams{$key};
38             }
39            
40 0 0         unless( defined($params{device}) ) {
41             my $dev = HiPi::Device::SPI->new(
42             speed => $params{speed},
43             bitsperword => $params{bitsperword},
44             delay => $params{delay},
45             devicename => $params{devicename},
46 0           );
47            
48 0           $params{device} = $dev;
49             }
50            
51 0           $params{max_channel} = ( $params{ic} >> 8 ) -1;
52 0           $params{hsb_mask} = $params{ic} & 0xFF;
53 0 0         $params{devbits} = ( $params{hsb_mask} == 0xF ) ? 12 : 10;
54            
55 0           my $self = $class->SUPER::new(%params);
56            
57             # MCP3xxx may need a dummy read on first use after boot
58             # as the chip needs the CS line to transition low/hi at
59             # least once if it is booted when CS is low
60            
61 0           $self->single_read(0);
62            
63 0           return $self;
64             }
65              
66             sub read {
67 0     0 0   my($self, $mode) = @_;
68            
69 0 0         my @buffers = ( $self->devbits == 12 )
70             ? ( 4 + ( $mode >> 2 ), ( $mode & 0x3 ) << 6, 0 ) # 12 bit
71             : ( 1, $mode << 4 , 0 ); # 10 bit
72            
73 0           my @result = unpack('C3', $self->device->transfer( pack('C3', @buffers) ));
74 0           return ( ($result[1] & $self->hsb_mask ) << 8 ) + $result[2];
75             }
76              
77             sub single_read {
78 0     0 0   my($self, $channel) = @_;
79 0   0       $channel //= 0;
80 0 0 0       die qq(bad channel number $channel) if( $channel < 0 || $channel > $self->max_channel);
81 0           $channel &= 0x7;
82 0           return $self->read( 8 + $channel );
83             }
84              
85             sub diff_read {
86 0     0 0   my($self, $channel) = @_;
87             #channel must be below max channels
88 0 0 0       die qq(bad channel number $channel) if($channel !~ /^\d$/ || $channel > $self->max_channel);
89 0           return $self->read( $channel );
90             }
91              
92             sub percent_read {
93 0     0 0   my($self, $channel) = @_;
94 0           my $raw = $self->single_read( $channel );
95 0 0         return $raw if !$raw;
96 0 0         my $div = ( $self->devbits == 12 ) ? 4095 : 1023;
97 0           my $float = ( $raw / $div ) * 100;
98 0           my $result = sprintf('%.0f', $float);
99 0           return $result;
100             }
101              
102             1;
103              
104             __END__