File Coverage

blib/lib/Device/BusPirate/Chip/INA219.pm
Criterion Covered Total %
statement 27 66 40.9
branch 0 2 0.0
condition n/a
subroutine 9 24 37.5
pod 2 7 28.5
total 38 99 38.3


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2014 -- leonerd@leonerd.org.uk
5              
6             package Device::BusPirate::Chip::INA219;
7              
8 1     1   630 use strict;
  1         2  
  1         41  
9 1     1   5 use warnings;
  1         2  
  1         27  
10 1     1   29 use 5.010;
  1         2  
  1         28  
11 1     1   4 use base qw( Device::BusPirate::Chip );
  1         2  
  1         564  
12              
13             our $VERSION = '0.01';
14              
15 1     1   376 use Carp;
  1         1  
  1         69  
16 1     1   548 use Data::Bitfield qw( bitfield boolfield enumfield );
  1         1261  
  1         98  
17              
18 1     1   6 use constant CHIP => "INA219";
  1         1  
  1         59  
19 1     1   4 use constant MODE => "I2C";
  1         2  
  1         314  
20              
21             =head1 NAME
22              
23             C - use an F chip with C
24              
25             =head1 DESCRIPTION
26              
27             This L subclass provides specific communication to a
28             F F chip attached to the F via I2C.
29              
30             The reader is presumed to be familiar with the general operation of this chip;
31             the documentation here will not attempt to explain or define chip-specific
32             concepts or features, only the use of this module to access them.
33              
34             =cut
35              
36             sub new
37             {
38 0     0 1   my $class = shift;
39 0           my ( $bp, %opts ) = @_;
40              
41 0           my $self = $class->SUPER::new( @_ );
42              
43 0           $self->{$_} = $opts{$_} for qw( address );
44              
45 0           return $self;
46             }
47              
48             =head1 METHODS
49              
50             The following methods documented with a trailing call to C<< ->get >> return
51             L instances.
52              
53             =cut
54              
55             sub read_register
56             {
57 0     0 0   my $self = shift;
58 0           my ( $reg ) = @_;
59              
60             $self->mode->send( $self->{address}, chr $reg )
61 0     0     ->then( sub { $self->mode->recv( $self->{address}, 2 ) })
62 0     0     ->then( sub { my ( $data ) = @_; Future->done( unpack 's>', $data ) });
  0            
  0            
63             }
64              
65             sub write_register
66             {
67 0     0 0   my $self = shift;
68 0           my ( $reg, $value ) = @_;
69              
70 0           $self->mode->send( $self->{address}, chr( $reg ) . pack 's>', $value );
71             }
72              
73             use constant {
74 1         464 REG_CONFIG => 0x00, # R/W
75             REG_VSHUNT => 0x01, # R
76             REG_VBUS => 0x02, # R
77             REG_POWER => 0x03, # R
78             REG_CURRENT => 0x04, # R
79             REG_CALIB => 0x05, # R/W
80 1     1   5 };
  1         2  
81              
82             my @ADCs = qw( 9b 10b 11b 12b . . . . 1 2 4 8 16 32 64 128 );
83              
84             bitfield CONFIG =>
85             RST => boolfield(15),
86             BRNG => enumfield(13, qw( 16V 32V )),
87             PG => enumfield(11, qw( 40mV 80mV 160mV 320mV )),
88             BADC => enumfield( 7, @ADCs),
89             SADC => enumfield( 3, @ADCs),
90             MODE_CONT => boolfield(2),
91             MODE_BUS => boolfield(1),
92             MODE_SHUNT => boolfield(0);
93              
94             =head2 $config = $ina->read_config->get
95              
96             Reads and returns the current chip configuration as a C reference.
97              
98             =cut
99              
100             sub read_config
101             {
102 0     0 0   my $self = shift;
103              
104             $self->read_register( REG_CONFIG )->then( sub {
105 0     0     my ( $data ) = @_;
106 0           Future->done( $self->{config} = { unpack_CONFIG( $data ) } );
107 0           });
108             }
109              
110             sub _config
111             {
112 0     0     my $self = shift;
113              
114             defined $self->{config}
115             ? Future->done( $self->{config} )
116 0 0   0     : $self->read_config->then( sub { Future->done( $self->{config} ) } );
  0            
117             }
118              
119             =head2 $ina->change_config( %config )->get
120              
121             Changes the configuration. Any field names not mentioned will be preserved.
122              
123             =cut
124              
125             sub change_config
126             {
127 0     0 1   my $self = shift;
128 0           my %changes = @_;
129              
130             $self->_config->then( sub {
131 0     0     my %config = ( %{ $_[0] }, %changes );
  0            
132              
133 0           undef $self->{config}; # invalidate the cache
134 0           $self->write_register( REG_CONFIG, pack_CONFIG( %config ) );
135 0           });
136             }
137              
138             =head2 $uv = $ina->read_shunt_voltage->get
139              
140             Returns the current shunt voltage reading scaled integer in microvolts.
141              
142             =cut
143              
144             sub read_shunt_voltage
145             {
146 0     0 0   my $self = shift;
147              
148             $self->read_register( REG_VSHUNT )->then( sub {
149 0     0     my ( $vraw ) = @_;
150              
151             # Each $vraw graduation is 10uV
152 0           Future->done( $vraw * 10 );
153 0           });
154             }
155              
156             =head2 $mv = $ina->read_bus_voltage->get
157              
158             =head2 ( $mv, $ovf, $cnvr ) = $ina->read_bus_voltage->get
159              
160             Returns the current bus voltage reading, as a scaled integer in milivolts.
161              
162             The returned L also yields the OVF and CNVR flags.
163              
164             =cut
165              
166             sub read_bus_voltage
167             {
168 0     0 0   my $self = shift;
169              
170             $self->read_register( REG_VBUS )->then( sub {
171 0     0     my ( $value ) = @_;
172 0           my $ovf = ( $value & 1<<0 );
173 0           my $cnvr = ( $value & 1<<1 );
174 0           my $vraw = $value >> 3;
175              
176             # Each $vraw graduation is 4mV
177 0           Future->done( $vraw * 4, $cnvr, $ovf );
178 0           });
179             }
180              
181             =head1 AUTHOR
182              
183             Paul Evans
184              
185             =cut
186              
187             0x55AA;