File Coverage

blib/lib/Device/Chip/INA219.pm
Criterion Covered Total %
statement 64 64 100.0
branch 2 4 50.0
condition 1 2 50.0
subroutine 14 14 100.0
pod 4 5 80.0
total 85 89 95.5


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-2021 -- leonerd@leonerd.org.uk
5              
6 3     3   187553 use v5.26;
  3         26  
7 3     3   409 use Object::Pad 0.57;
  3         7416  
  3         12  
8              
9             package Device::Chip::INA219 0.08;
10             class Device::Chip::INA219
11 3     3   1369 :isa(Device::Chip::Base::RegisteredI2C 0.10);
  3         19604  
  3         104  
12              
13 3     3   371 use constant REG_DATA_SIZE => 16;
  3         5  
  3         124  
14              
15 3     3   15 use utf8;
  3         5  
  3         9  
16              
17 3     3   65 use Carp;
  3         3  
  3         120  
18 3     3   15 use Future::AsyncAwait;
  3         4  
  3         10  
19              
20 3     3   1141 use Data::Bitfield qw( bitfield boolfield enumfield );
  3         5155  
  3         524  
21              
22             =encoding UTF-8
23              
24             =head1 NAME
25              
26             C - chip driver for an F
27              
28             =head1 SYNOPSIS
29              
30             use Device::Chip::INA219;
31             use Future::AsyncAwait;
32              
33             my $chip = Device::Chip::INA219->new;
34             await $chip->mount( Device::Chip::Adapter::...->new );
35              
36             printf "Current bus voltage is %d mV, shunt voltage is %d uV\n",
37             await $chip->read_bus_voltage, await $chip->read_shunt_voltage;
38              
39             =head1 DESCRIPTION
40              
41             This L subclass provides specific communication to a
42             F F attached to a computer via an I²C adapter.
43              
44             The reader is presumed to be familiar with the general operation of this chip;
45             the documentation here will not attempt to explain or define chip-specific
46             concepts or features, only the use of this module to access them.
47              
48             =cut
49              
50             =head1 MOUNT PARAMETERS
51              
52             =head2 addr
53              
54             The I²C address of the device. Can be specified in decimal, octal or hex with
55             leading C<0> or C<0x> prefixes.
56              
57             =cut
58              
59 2         4 method I2C_options ( %params )
  2         3  
  2         2  
60 2     2 0 618 {
61 2   50     10 my $addr = delete $params{addr} // 0x40;
62 2 50       8 $addr = oct $addr if $addr =~ m/^0/;
63              
64             return (
65 2         9 addr => $addr,
66             max_bitrate => 100E3,
67             );
68             }
69              
70             =head1 METHODS
71              
72             The following methods documented in an C expression return L
73             instances.
74              
75             =cut
76              
77             use constant {
78 3         2515 REG_CONFIG => 0x00, # R/W
79             REG_VSHUNT => 0x01, # R
80             REG_VBUS => 0x02, # R
81             REG_POWER => 0x03, # R
82             REG_CURRENT => 0x04, # R
83             REG_CALIB => 0x05, # R/W
84 3     3   18 };
  3         6  
85              
86             my @ADCs = qw( 9b 10b 11b 12b . . . . 1 2 4 8 16 32 64 128 );
87              
88             # We'll use integer encoding and pack/unpack it ourselves because the BADC
89             # field spans a byte boundary the wrong way
90             bitfield { format => "integer" }, CONFIG =>
91             RST => boolfield(15),
92             BRNG => enumfield(13, qw( 16V 32V )),
93             PG => enumfield(11, qw( 40mV 80mV 160mV 320mV )),
94             BADC => enumfield( 7, @ADCs),
95             SADC => enumfield( 3, @ADCs),
96             MODE_CONT => boolfield(2),
97             MODE_BUS => boolfield(1),
98             MODE_SHUNT => boolfield(0);
99              
100             =head2 read_config
101              
102             $config = await $chip->read_config;
103              
104             Reads and returns the current chip configuration as a C reference.
105              
106             RST => BOOL
107             BRNG => "16V" | "32V"
108             PG => "40mV" | "80mV" | "160mV" | "320mV"
109             BADC => "9b" | "10b" | "11b" | "12b" | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128
110             SADC => as above
111             MODE_CONT => BOOL
112             MODE_BUS => BOOL
113             MODE_SHUNT => BOOL
114              
115             =cut
116              
117             has $_config;
118              
119 1         1 async method read_config ()
  1         1  
120 1         3 {
121 1         5 my $bytes = await $self->cached_read_reg( REG_CONFIG, 1 );
122              
123 1         7564 return $_config = { unpack_CONFIG( unpack "S>", $bytes ) };
124 1     1 1 194 }
125              
126             =head2 change_config
127              
128             await $chip->change_config( %config );
129              
130             Changes the configuration. Any field names not mentioned will be preserved.
131              
132             =cut
133              
134 1         2 async method change_config ( %changes )
  1         2  
  1         2  
135 1         3 {
136 1 50       3 defined $_config or await $self->read_config;
137              
138 1         1 my %config = ( %{ $_config }, %changes );
  1         7  
139              
140 1         3 undef $_config; # invalidate the cache
141              
142 1         5 await $self->write_reg( REG_CONFIG, pack "S>", pack_CONFIG( %config ) );
143 1     1 1 3919 }
144              
145             =head2 read_shunt_voltage
146              
147             $uv = await $chip->read_shunt_voltage;
148              
149             Returns the current shunt voltage reading scaled integer in microvolts.
150              
151             =cut
152              
153 1         2 async method read_shunt_voltage ()
  1         1  
154 1         2 {
155 1         14 my $vraw = unpack "s>", await $self->read_reg( REG_VSHUNT, 1 );
156              
157             # Each $vraw graduation is 10uV
158 1         6503 return $vraw * 10;
159 1     1 1 180 }
160              
161             =head2 read_bus_voltage
162              
163             $mv = await $chip->read_bus_voltage;
164              
165             ( $mv, $ovf, $cnvr ) = await $chip->read_bus_voltage;
166              
167             Returns the current bus voltage reading, as a scaled integer in milivolts.
168              
169             The returned L also yields the OVF and CNVR flags.
170              
171             =cut
172              
173 1         2 async method read_bus_voltage ()
  1         1  
174 1         3 {
175 1         4 my $value = unpack "s>", await $self->read_reg( REG_VBUS, 1 );
176              
177 1         1012 my $ovf = ( $value & 1<<0 );
178 1         2 my $cnvr = ( $value & 1<<1 );
179 1         2 my $vraw = $value >> 3;
180              
181             # Each $vraw graduation is 4mV
182 1         4 return $vraw * 4, $cnvr, $ovf;;
183 1     1 1 2648 }
184              
185             =head1 AUTHOR
186              
187             Paul Evans
188              
189             =cut
190              
191             0x55AA;