File Coverage

blib/lib/Device/Chip/MCP4725.pm
Criterion Covered Total %
statement 47 53 88.6
branch 4 6 66.6
condition 2 8 25.0
subroutine 9 10 90.0
pod 4 5 80.0
total 66 82 80.4


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, 2016-2022 -- leonerd@leonerd.org.uk
5              
6 2     2   130797 use v5.26;
  2         21  
7 2     2   11 use Object::Pad 0.57;
  2         23  
  2         10  
8              
9             package Device::Chip::MCP4725 0.14;
10             class Device::Chip::MCP4725
11             :isa(Device::Chip);
12              
13 2     2   640 use Carp;
  2         6  
  2         118  
14 2     2   13 use Future::AsyncAwait;
  2         3  
  2         10  
15              
16 2     2   104 use constant PROTOCOL => "I2C";
  2         4  
  2         2209  
17              
18             =encoding UTF-8
19              
20             =head1 NAME
21              
22             C - chip driver for F
23              
24             =head1 SYNOPSIS
25              
26             use Device::Chip::MCP4725;
27             use Future::AsyncAwait;
28              
29             my $chip = Device::Chip::MCP4725->new;
30             await $chip->mount( Device::Chip::Adapter::...->new );
31              
32             # Presuming Vcc = 5V
33             await $chip->write_dac_ratio( 1.23 / 5 );
34             print "Output is now set to 1.23V\n";
35              
36             =head1 DESCRIPTION
37              
38             This L subclass provides specific communication to a
39             F F attached to a computer via an I²C adapter.
40              
41             The reader is presumed to be familiar with the general operation of this chip;
42             the documentation here will not attempt to explain or define chip-specific
43             concepts or features, only the use of this module to access them.
44              
45             =cut
46              
47             =head1 MOUNT PARAMETERS
48              
49             =head2 addr
50              
51             The I²C address of the device. Can be specified in decimal, octal or hex with
52             leading C<0> or C<0x> prefixes.
53              
54             =cut
55              
56             sub I2C_options ( $, %params )
57 1     1 0 377 {
  1         2  
  1         3  
58 1   50     7 my $addr = delete $params{addr} // 0x60;
59 1 50       4 $addr = oct $addr if $addr =~ m/^0/;
60              
61             return (
62 1         6 addr => $addr,
63             max_bitrate => 400E3,
64             );
65             }
66              
67             =head1 ACCESSORS
68              
69             The following methods documented in an C expression return L
70             instances.
71              
72             =cut
73              
74             my @POWERDOWN_TO_NAME = qw( normal 1k 100k 500k );
75             my %NAME_TO_POWERDOWN = map { $POWERDOWN_TO_NAME[$_] => $_ } 0 .. $#POWERDOWN_TO_NAME;
76              
77             =head2 read_config
78              
79             $config = await $chip->read_config;
80              
81             Returns a C reference containing the chip's current configuration
82              
83             RDY => 0 | 1
84             POR => 0 | 1
85              
86             PD => "normal" | "1k" | "100k" | "500k"
87             DAC => 0 .. 4095
88              
89             EEPROM_PD => "normal" | "1k" | "100k" | "500k"
90             EEPROM_DAC => 0 .. 4095
91              
92             =cut
93              
94 1         2 async method read_config ()
  1         2  
95 1         3 {
96 1         6 my $bytes = await $self->protocol->read( 5 );
97 1         8974 my ( $status, $dac, $eeprom ) = unpack( "C S> S>", $bytes );
98              
99             return {
100 1         20 RDY => !!( $status & 0x80 ),
101             POR => !!( $status & 0x40 ),
102             PD => $POWERDOWN_TO_NAME[ ( $status & 0x06 ) >> 1 ],
103              
104             DAC => $dac >> 4,
105              
106             EEPROM_PD => $POWERDOWN_TO_NAME[ ( $eeprom & 0x6000 ) >> 13 ],
107             EEPROM_DAC => ( $eeprom & 0x0FFF ),
108             };
109 1     1 1 299 }
110              
111             =head1 METHODS
112              
113             =cut
114              
115             =head2 write_dac
116              
117             await $chip->write_dac( $dac, $powerdown );
118              
119             Writes a new value for the DAC output and powerdown state in "fast" mode.
120              
121             C<$powerdown> is optional and will default to 0 if not provided.
122              
123             =cut
124              
125 2         4 async method write_dac ( $dac, $powerdown = undef )
  2         4  
  2         4  
  2         3  
126 2         6 {
127 2         4 $dac &= 0x0FFF;
128              
129 2         3 my $pd = 0;
130 2 100 33     9 $pd = $NAME_TO_POWERDOWN{$powerdown} // croak "Unrecognised powerdown state '$powerdown'"
131             if defined $powerdown;
132              
133 2         7 await $self->protocol->write( pack "S>", $pd << 12 | $dac );
134 2     2 1 7384 }
135              
136             =head2 write_dac_ratio
137              
138             await $chip->write_dac_ratio( $ratio );
139              
140             Writes a new value for the DAC output, setting it to normal output for a given
141             ratio between 0 and 1.
142              
143             =cut
144              
145 0         0 async method write_dac_ratio ( $ratio )
  0         0  
  0         0  
146 0         0 {
147 0         0 await $self->write_dac_ratio( $ratio * 2**12 );
148 0     0 1 0 }
149              
150             =head2 write_dac_and_eeprom
151              
152             $chip->write_dac_and_eeprom( $dac, $powerdown )
153              
154             As L but also updates the EEPROM with the same values.
155              
156             =cut
157              
158 1         2 async method write_dac_and_eeprom ( $dac, $powerdown = undef )
  1         2  
  1         2  
  1         2  
159 1         4 {
160 1         3 $dac &= 0x0FFF;
161              
162 1         2 my $pd = 0;
163 1 50 0     4 $pd = $NAME_TO_POWERDOWN{$powerdown} // croak "Unrecognised powerdown state '$powerdown'"
164             if defined $powerdown;
165              
166 1         4 await $self->protocol->write( pack "C S>", 0x60 | $pd << 1, $dac << 4 );
167 1     1 1 3619 }
168              
169             =head1 AUTHOR
170              
171             Paul Evans
172              
173             =cut
174              
175             0x55AA;