File Coverage

blib/lib/Device/BusPirate/Chip/MPL3115A2.pm
Criterion Covered Total %
statement 24 52 46.1
branch 0 4 0.0
condition n/a
subroutine 8 23 34.7
pod 1 4 25.0
total 33 83 39.7


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, 2015 -- leonerd@leonerd.org.uk
5              
6             package Device::BusPirate::Chip::MPL3115A2;
7              
8 1     1   625 use strict;
  1         1  
  1         33  
9 1     1   4 use warnings;
  1         2  
  1         29  
10 1     1   9 use base qw( Device::BusPirate::Chip );
  1         1  
  1         496  
11              
12             our $VERSION = '0.01';
13              
14 1     1   386 use Carp;
  1         1  
  1         63  
15              
16 1     1   4 use constant CHIP => "MPL3115A2";
  1         1  
  1         51  
17 1     1   4 use constant MODE => "I2C";
  1         1  
  1         40  
18              
19             =head1 NAME
20              
21             C - use a F chip with C
22              
23             =head1 DESCRIPTION
24              
25             This L subclass provides specific communication to a
26             F F chip attached to the F via
27             I2C.
28              
29             The reader is presumed to be familiar with the general operation of this chip;
30             the documentation here will not attempt to explain or define chip-specific
31             concepts or features, only the use of this module to access them.
32              
33             =cut
34              
35             # This device has a constant address
36             my $ADDR = 0x60;
37              
38 1     1   4 use constant WHO_AM_I_ID => 0xC4;
  1         1  
  1         78  
39              
40             use constant {
41 1         761 REG_STATUS => 0x00,
42             REG_OUT_P_MSB => 0x01,
43             REG_OUT_P_CSB => 0x02,
44             REG_OUT_P_LSB => 0x03,
45             REG_OUT_T_MSB => 0x04,
46             REG_OUT_T_LSB => 0x05,
47             REG_DR_STATUS => 0x06,
48             REG_OUT_P_DELTA_MSB => 0x07,
49             REG_OUT_P_DELTA_CSB => 0x08,
50             REG_OUT_P_DELTA_LSB => 0x09,
51             REG_OUT_T_DELTA_MSB => 0x0A,
52             REG_OUT_T_DELTA_LSB => 0x0B,
53             REG_WHO_AM_I => 0x0C,
54             REG_F_STATUS => 0x0D,
55             REG_F_DATA => 0x0E,
56             REG_F_SETUP => 0x0F,
57             REG_TIME_DLY => 0x10,
58             REG_SYSMOD => 0x11,
59             REG_INT_SOURCE => 0x12,
60             REG_PT_DATA_CFG => 0x13,
61             REG_BAR_IN_MSB => 0x14,
62             REG_BAR_IN_LSB => 0x15,
63             REG_P_TGT_MSB => 0x16,
64             REG_P_TGT_LSB => 0x17,
65             REG_T_TGT => 0x18,
66             REG_P_WND_MSB => 0x19,
67             REG_P_WND_LSB => 0x1A,
68             REG_T_WND => 0x1B,
69             REG_P_MIN_MSB => 0x1C,
70             REG_P_MIN_CSB => 0x1D,
71             REG_P_MIN_LSB => 0x1E,
72             REG_T_MIN_MSB => 0x1F,
73             REG_T_MIN_LSB => 0x20,
74             REG_P_MAX_MSB => 0x21,
75             REG_P_MAX_CSB => 0x22,
76             REG_P_MAX_LSB => 0x23,
77             REG_T_MAX_MSB => 0x24,
78             REG_T_MAX_LSB => 0x25,
79             REG_CTRL_REG1 => 0x26,
80             REG_CTRL_REG2 => 0x27,
81             REG_CTRL_REG3 => 0x28,
82             REG_CTRL_REG4 => 0x29,
83             REG_CTRL_REG5 => 0x2A,
84             REG_OFF_P => 0x2B,
85             REG_OFF_T => 0x2C,
86             REG_OFF_H => 0x2D,
87 1     1   6 };
  1         1  
88              
89             sub _mplread
90             {
91 0     0     my $self = shift;
92 0           my ( $reg, $len ) = @_;
93              
94 0           $self->mode->send_then_recv( $ADDR, pack( "C", $reg ), $len );
95             }
96              
97             sub _mplwrite
98             {
99 0     0     my $self = shift;
100 0           my ( $reg, $val ) = @_;
101              
102 0           $self->mode->send( $ADDR, pack( "C", $reg ) . $val );
103             }
104              
105             # Raw 8-bit integers
106             sub _mplread8 { $_[0]->_mplread( $_[1], 1 )
107 0     0     ->then( sub { Future->done( unpack "C", $_[0] ) } ) }
  0     0      
108 0     0     sub _mplwrite8 { $_[0]->_mplwrite( $_[1], pack "C", $_[2] ) }
109              
110             # Converted pressure
111             sub _mplread_p { $_[0]->_mplread( $_[1], 3 )
112 0     0     ->then( sub { Future->done( unpack( "L>", "\0" . $_[0] ) / 64 ) } ) }
  0     0      
113              
114             # Converted temperature
115             sub _mplread_t { $_[0]->_mplread( $_[1], 2 )
116             ->then( sub {
117 0     0     my ( $msb, $lsb ) = unpack "cC", $_[0];
118 0     0     Future->done( $msb + ( $lsb / 256 ) ) }) }
  0            
119              
120             =head1 ACCESSORS
121              
122             The following methods documented with a trailing call to C<< ->get >> return
123             L instances.
124              
125             =cut
126              
127             =head2 $pressure = $mpl->read_pressure->get
128              
129             Returns the value of the C registers, suitably converted into
130             Pascals. (The chip must I be in C mode for the conversion to work).
131              
132             =cut
133              
134 0     0 0   sub read_pressure { shift->_mplread_p( REG_OUT_P_MSB ) }
135              
136             =head2 $temperature = $mpl->read_temperature->get
137              
138             Returns the value of the C registers, suitable converted into degrees
139             C. (The chip must I be in C mode for the conversion to work).
140              
141             =cut
142              
143 0     0 0   sub read_temperature { shift->_mplread_t( REG_OUT_T_MSB ) }
144              
145             =head1 METHODS
146              
147             =cut
148              
149             =head2 $mpl->check_id->get
150              
151             Reads the C register and checks for a valid ID result. The returned
152             future fails if the expected result is not received.
153              
154             =cut
155              
156             sub check_id
157             {
158 0     0 0   my $self = shift;
159              
160             $self->_mplread8( REG_WHO_AM_I )->then( sub {
161 0     0     my ( $id ) = @_;
162 0 0         $id == WHO_AM_I_ID or
163             die sprintf "Incorrect response from WHO_AM_I register (got %02X, expected %02X)\n",
164             $id, WHO_AM_I_ID;
165              
166 0           Future->done( $self );
167 0           });
168             }
169              
170             =head2 $mpl->active( $on )->get
171              
172             Sets/clears the C bit in C, which activates the actual
173             device. This must be set before pressure / temperature readings will be made.
174              
175             =cut
176              
177             sub active
178             {
179 0     0 1   my $self = shift;
180 0           my ( $on ) = @_;
181              
182             $self->_mplread8( REG_CTRL_REG1 )->then( sub {
183 0     0     my ( $val ) = @_;
184 0           $val = ( $val & ~1 );
185 0 0         $val |= 1 if $on;
186 0           $self->_mplwrite8( REG_CTRL_REG1, $val );
187 0           });
188             }
189              
190             =head1 AUTHOR
191              
192             Paul Evans
193              
194             =cut
195              
196             0x55AA;