File Coverage

blib/lib/Device/Chip.pm
Criterion Covered Total %
statement 31 42 73.8
branch 3 4 75.0
condition 3 8 37.5
subroutine 8 10 80.0
pod 2 4 50.0
total 47 68 69.1


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-2022 -- leonerd@leonerd.org.uk
5              
6 9     9   101484 use v5.26;
  9         42  
7 9     9   601 use Object::Pad 0.66;
  9         10924  
  9         45  
8              
9             package Device::Chip 0.25;
10             class Device::Chip :repr(HASH);
11              
12 9     9   3147 use Carp;
  9         23  
  9         687  
13              
14 9     9   2002 use Future::AsyncAwait 0.38; # async method
  9         71870  
  9         68  
15              
16             =head1 NAME
17              
18             C - an abstraction of a hardware chip IO driver
19              
20             =head1 DESCRIPTION
21              
22             =over 2
23              
24             B: this document is currently under heavy development. Details will be
25             added, changed, and evolved as it progresses. Be warned that currently
26             anything may be changed from one version to the next.
27              
28             =back
29              
30             This package describes an interface that classes can use to implement a driver
31             to talk to a specific hardware chip or module. An instance implementing this
32             interface would communicate with the actual hardware device via some instance
33             of the related interface, L.
34              
35             The documentation in this file is aimed primarily at users of C
36             subclasses. For more information on authoring such a module, see instead
37             L.
38              
39             =head2 USING A CHIP DRIVER
40              
41             To actually use a chip driver to talk to a specific piece of hardware that is
42             connected to the computer, an adapter must be supplied. This will be an
43             instance of some class that satisfies the L interface.
44             The chip driver will use this adapter instance to access the underlying
45             hardware port used to electrically connect to the chip and communicate with
46             it. This is supplied by invoking the L method. For example:
47              
48             my $chip = Device::Chip::MAX7219->new;
49              
50             my $adapter = Device::Chip::Adapter::FTDI->new;
51              
52             await $chip->mount( $adapter );
53              
54             =cut
55              
56             =head1 CONSTRUCTOR
57              
58             =cut
59              
60             =head2 new
61              
62             $chip = Device::Chip->new;
63              
64             Returns a new instance of a chip driver object.
65              
66             =cut
67              
68             =head1 METHODS
69              
70             The following methods documented in an C expression return L
71             instances.
72              
73             This allows them to easily be used as a simple synchronous method by using the
74             trailing L call. Alternatively, if the underlying adapter allows a
75             fully asynchronous mode of operation, they can be combined in the usual ways
76             for futures to provide more asynchronous use of the device.
77              
78             =cut
79              
80             field $_adapter;
81             method adapter
82 0     0 0 0 {
83 0   0     0 return $_adapter //
84             croak "This chip has not yet been mounted on an adapter";
85             }
86              
87             field $_protocol;
88             method protocol
89 17     17 0 39 {
90 17   33     108 return $_protocol //
91             croak "This chip has not yet been connected to a protocol";
92             }
93              
94             =head2 mount
95              
96             $chip = await $chip->mount( $adapter, %params );
97              
98             Supplies the chip driver with the means to actually communicate with the
99             connected device, via some electrical interface connected to the computer.
100              
101             The parameters given in C<%params> will vary depending on the specific chip in
102             question, and should be documented there.
103              
104             =cut
105              
106 2         4 async method mount ( $adapter, %params )
  2         38  
  2         6  
  2         4  
107 2         7 {
108 2         3 $_adapter = $adapter;
109              
110 2         13 my $pname = $self->PROTOCOL;
111              
112 2         11 $_protocol = await $_adapter->make_protocol( $pname );
113              
114 2 50       473 my $code = $self->can( "${pname}_options" ) or
115             return $self;
116              
117 0         0 await $self->protocol->configure(
118             $self->$code( %params )
119             );
120              
121 0         0 return $self;
122 2     2 1 16 }
123              
124             # Perl 5.36+ can distinguish this; but this still works fine on older perls
125 9     9   4517 use constant true => (1 == 1);
  9         22  
  9         3644  
126              
127             sub _parse_options ( $, $str )
128 4     4   6 {
  4         8  
  4         5  
129 4 100 100     19 return map { m/^([^=]+)=(.*)$/ ? ( $1 => $2 ) : ( $_ => true ) }
  4         29  
130             split m/,/, $str // "";
131              
132             }
133              
134             =head2 mount_from_paramstr
135              
136             $chip = await $chip->mount_from_paramstr( $adapter, $paramstr );
137              
138             A variant of L that parses its options from the given string. This
139             string should be a comma-separated list of parameters, where each is given as
140             a name and value separated by equals sign. If there is no equals sign, the
141             value is implied as true, as a convenience for parameters that are simple
142             boolean flags.
143              
144             =cut
145              
146 0           async method mount_from_paramstr ( $adapter, $paramstr )
  0            
  0            
  0            
147 0           {
148 0           await $self->mount( $adapter, $self->_parse_options( $paramstr ) );
149 0     0 1   }
150              
151             =head1 AUTHOR
152              
153             Paul Evans
154              
155             =cut
156              
157             0x55AA;