File Coverage

blib/lib/VIC/PIC/Functions/ADC.pm
Criterion Covered Total %
statement 45 63 71.4
branch 15 36 41.6
condition 6 20 30.0
subroutine 7 8 87.5
pod 0 3 0.0
total 73 130 56.1


line stmt bran cond sub pod time code
1             package VIC::PIC::Functions::ADC;
2 31     31   18718 use strict;
  31         43  
  31         926  
3 31     31   131 use warnings;
  31         38  
  31         1615  
4             our $VERSION = '0.31';
5             $VERSION = eval $VERSION;
6 31     31   123 use Carp;
  31         38  
  31         1745  
7 31     31   133 use POSIX ();
  31         39  
  31         448  
8 31     31   101 use Moo::Role;
  31         43  
  31         184  
9              
10             sub adc_enable {
11 3     3 0 20 my $self = shift;
12 3 50       10 return unless $self->doesroles(qw(GPIO ADC Chip CodeGen));
13 3 50 33     27 unless (defined $self->adc_channels and $self->adc_channels > 0) {
14 0         0 carp $self->type, " has no ADC";
15 0         0 return;
16             }
17 3 50 33     29 unless (exists $self->registers->{ADCON0} and
18             exists $self->registers->{ADCON1}) {
19 0         0 carp $self->type, " has no valid ADCON0/ADCON1 registers";
20 0         0 return;
21             }
22 3 50       7 if (@_) {
23 3         6 my ($clock, $channel) = @_;
24 3         15 my $f_osc = $self->f_osc;
25 3 50       36 my $scale = POSIX::ceil(($f_osc / 4) / $clock) if $clock > 0;
26 3 50       11 $scale = 2 unless $clock;
27 3 50       9 $scale = 2 if $scale < 2;
28 3         14 my $adcs = $self->adcs_bits->{$scale};
29 3 50       17 $adcs = $self->adcs_bits->{internal} if $self->code_config->{adc}->{internal};
30 3         8 my $adcon1 = "0$adcs" . '0000';
31 3         7 my $code = << "...";
32             \tbanksel ADCON1
33             \tmovlw B'$adcon1'
34             \tmovwf ADCON1
35             ...
36 3 50       6 if (defined $channel) {
37             my $adfm = defined $self->code_config->{adc}->{right_justify} ?
38 3 50       15 $self->code_config->{adc}->{right_justify} : 1;
39 3   50     19 my $vcfg = $self->code_config->{adc}->{vref} || 0;
40 3         12 my $chs = $self->adc_chs_bits->{$channel};
41 3         7 my $adcon0 = "$adfm$vcfg$chs" . '01';
42 3         8 $code .= << "...";
43             \tbanksel ADCON0
44             \tmovlw B'$adcon0'
45             \tmovwf ADCON0
46             ...
47             }
48 3         7 return $code;
49             }
50             # no arguments have been given
51 0         0 return << "...";
52             \tbanksel ADCON0
53             \tbsf ADCON0, ADON
54             ...
55             }
56              
57             sub adc_disable {
58 0     0 0 0 my $self = shift;
59 0 0       0 return unless $self->doesroles(qw(ADC));
60 0 0 0     0 unless (defined $self->adc_channels and $self->adc_channels > 0) {
61 0         0 carp $self->type, " has no ADC";
62 0         0 return;
63             }
64 0 0       0 unless (exists $self->registers->{ADCON0}) {
65 0         0 carp $self->type, " has no valid ADCON0/ADCON1 registers";
66 0         0 return;
67             }
68 0         0 return << "...";
69             \tbanksel ADCON0
70             \tbcf ADCON0, ADON
71             ...
72             }
73              
74             sub adc_read {
75             #TODO: if the variable is 16-bit the varlow should be auto-adjusted
76 3     3 0 18 my ($self, $varhigh, $varlow) = @_;
77 3 50       9 return unless $self->doesroles(qw(ADC GPIO Chip));
78 3 50 33     32 unless (defined $self->adc_channels and $self->adc_channels > 0) {
79 0         0 carp $self->type, " has no ADC";
80 0         0 return;
81             }
82 3         4 $varhigh = uc $varhigh;
83 3 50       9 $varlow = uc $varlow if defined $varlow;
84 3 50 33     37 unless (exists $self->registers->{ADCON0} and
      33        
85             exists $self->registers->{ADRESH} and
86             exists $self->registers->{ADRESL}) {
87 0         0 carp $self->type, " has no valid ADCON0/ADRESH/ADRESL registers";
88 0         0 return;
89             }
90 3         8 my $code = << "...";
91             \t;;;delay 5us
92             \tnop
93             \tnop
94             \tnop
95             \tnop
96             \tnop
97             \tbsf ADCON0, GO
98             \tbtfss ADCON0, GO
99             \tgoto \$ - 1
100             \tmovf ADRESH, W
101             \tmovwf $varhigh
102             ...
103 3 50       10 $code .= "\tmovf ADRESL, W\n\tmovwf $varlow\n" if defined $varlow;
104 3         6 return $code;
105             }
106              
107             1;
108             __END__