File Coverage

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