| 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 |
||||||
| 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 |
||||||
| 40 | F |
||||||
| 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 |
||||||
| 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 |
||||||
| 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; |