File Coverage

blib/lib/RPi/GPIOExpander/MCP23017.pm
Criterion Covered Total %
statement 15 103 14.5
branch 0 44 0.0
condition 0 14 0.0
subroutine 5 24 20.8
pod 14 14 100.0
total 34 199 17.0


line stmt bran cond sub pod time code
1             package RPi::GPIOExpander::MCP23017;
2              
3 12     12   39071 use strict;
  12         188  
  12         345  
4 12     12   56 use warnings;
  12         20  
  12         317  
5              
6 12     12   54 use Carp qw(croak);
  12         22  
  12         797  
7 12     12   67 use RPi::Const qw(:all);
  12         20  
  12         2978  
8              
9             our $VERSION = '0.01';
10              
11             require XSLoader;
12             XSLoader::load('RPi::GPIOExpander::MCP23017', $VERSION);
13              
14             use constant {
15 12         16332 BANK_A => 0,
16             BANK_B => 1,
17             REG_BITS_ON => 0xFF,
18             REG_BITS_OFF => 0x00,
19 12     12   81 };
  12         23  
20              
21             # operational methods
22              
23             sub new {
24 0     0 1   my ($class, $addr) = @_;
25 0           my $self = bless {}, $class;
26 0   0       $self->_fd(getFd($addr // 0x20));
27 0           return $self;
28             }
29             sub cleanup {
30 0     0 1   clean($_[0]->_fd);
31             }
32              
33             # pin methods
34              
35             sub mode {
36 0     0 1   my ($self, $pin, $mode) = @_;
37              
38 0 0         if (! defined $mode){
39 0 0         my $reg = $pin > 7 ? MCP23017_IODIRB : MCP23017_IODIRA;
40 0           my $bit = _pinBit($pin);
41 0           return getRegisterBit($self->_fd, $reg, $bit);
42             }
43              
44 0           _check_mode($mode);
45              
46 0           pinMode($self->_fd, $pin, $mode);
47             }
48             sub pullup {
49 0     0 1   my ($self, $pin, $state) = @_;
50              
51 0 0         if (! defined $state){
52 0 0         my $reg = $pin > 7 ? MCP23017_GPPUB : MCP23017_GPPUA;
53 0           my $bit = _pinBit($pin);
54 0           return getRegisterBit($self->_fd, $reg, $bit);
55             }
56              
57 0           _check_pullup($state);
58              
59 0           pullUp($self->_fd, $pin, $state);
60             }
61             sub read {
62 0     0 1   my ($self, $pin) = @_;
63 0           return readPin($self->_fd, $pin);
64             }
65             sub write {
66 0     0 1   my ($self, $pin, $state) = @_;
67              
68 0           _check_write($state);
69              
70 0           return writePin($self->_fd, $pin, $state);
71             }
72              
73             # bank methods
74              
75             sub mode_bank {
76 0     0 1   my ($self, $bank, $mode) = @_;
77              
78 0           _check_bank($bank);
79 0 0         my $reg = $bank == BANK_A ? MCP23017_IODIRA : MCP23017_IODIRB;
80              
81 0 0         if (! defined $mode){
82 0           return getRegister($self->_fd, $reg);
83             }
84              
85 0           _check_mode($mode);
86 0 0         $mode = REG_BITS_ON if $mode == MCP23017_INPUT;
87              
88 0           setRegister($self->_fd, $reg, $mode, "mode_bank()");
89              
90 0           return getRegister($self->_fd, $reg);
91             }
92             sub write_bank {
93 0     0 1   my ($self, $bank, $state) = @_;
94              
95 0           _check_bank($bank);
96 0           _check_write($state);
97              
98 0 0         my $reg = $bank == BANK_A ? MCP23017_GPIOA : MCP23017_GPIOB;
99 0 0         $state = REG_BITS_ON if $state == HIGH;
100              
101 0           setRegister($self->_fd, $reg, $state, "write_bank()");
102              
103 0           return getRegister($self->_fd, $reg);
104             }
105             sub pullup_bank {
106 0     0 1   my ($self, $bank, $state) = @_;
107              
108 0           _check_bank($bank);
109              
110 0 0         my $reg = $bank == BANK_A ? MCP23017_GPPUA : MCP23017_GPPUB;
111              
112 0 0         if (! defined $state){
113 0           return getRegister($self->_fd, $reg);
114             }
115              
116 0           _check_pullup($state);
117              
118 0 0         $state = REG_BITS_ON if $state == HIGH;
119              
120 0           setRegister($self->_fd, $reg, $state, "write_pullup()");
121              
122 0           return getRegister($self->_fd, $reg);
123             }
124              
125             # both bank (all) methods
126              
127             sub mode_all {
128 0     0 1   my ($self, $mode) = @_;
129              
130 0           _check_mode($mode);
131 0 0         $mode = REG_BITS_ON if $mode == MCP23017_INPUT;
132              
133 0           for my $reg (MCP23017_IODIRA .. MCP23017_IODIRB) {
134 0           setRegister($self->_fd, $reg, $mode, "mode_all()");
135             }
136             }
137             sub write_all {
138 0     0 1   my ($self, $state) = @_;
139              
140 0           _check_write($state);
141 0 0         $state = REG_BITS_ON if $state == HIGH;
142              
143 0           for my $reg (MCP23017_GPIOA .. MCP23017_GPIOB) {
144 0           setRegister($self->_fd, $reg, $state, "write_all()");
145             }
146             }
147             sub pullup_all {
148 0     0 1   my ($self, $state) = @_;
149              
150 0           _check_pullup($state);
151 0 0         $state = REG_BITS_ON if $state == MCP23017_INPUT;
152              
153 0           for my $reg (MCP23017_GPPUA .. MCP23017_GPPUB) {
154 0           setRegister($self->_fd, $reg, $state, "mode_all()");
155             }
156             }
157              
158             # register methods
159              
160             sub register {
161 0     0 1   my ($self, $reg, $data) = @_;
162              
163 0 0         if (defined $data){
164 0           setRegister($self->_fd, $reg, $data, 'register()');
165             }
166 0           return getRegister($self->_fd, $reg);
167             }
168             sub register_bit {
169 0     0 1   my ($self, $reg, $bit) = @_;
170              
171 0           my $regval = getRegisterBit($self->_fd, $reg, $bit);
172 0           return $regval;
173             }
174              
175             # internal/helper methods
176              
177             sub _check_bank {
178 0     0     my ($bank) = @_;
179 0 0 0       if ($bank != BANK_A && $bank != BANK_B){
180 0           croak "bank param must be either 0 or 1, not '$bank'\n";
181             }
182             }
183             sub _check_mode {
184 0     0     my ($mode) = @_;
185 0 0 0       if ($mode != MCP23017_INPUT && $mode != MCP23017_OUTPUT){
186 0           croak "mode param must be either 0 or 1, not '$mode'\n";
187             }
188             }
189             sub _check_pullup {
190 0     0     my ($state) = @_;
191              
192 0 0 0       if ($state != HIGH && $state != LOW){
193 0           croak "state param must be either 0 or 1, not '$state'\n";
194             }
195             }
196             sub _check_write {
197 0     0     my ($state) = @_;
198              
199 0 0         if (! defined $state){
200 0           croak "write() requires the state to be sent in\n";
201             }
202              
203 0 0 0       if ($state != HIGH && $state != LOW){
204 0           croak "state param must be either 0 or 1, not '$state'\n";
205             }
206             }
207             sub _fd {
208 0     0     my ($self, $fd) = @_;
209 0 0         $self->{fd} = $fd if defined $fd;
210 0           return $self->{fd};
211             }
212              
213             1;
214             __END__