File Coverage

blib/lib/VIC/PIC/P16F677.pm
Criterion Covered Total %
statement 12 12 100.0
branch 1 2 50.0
condition n/a
subroutine 4 4 100.0
pod 0 1 0.0
total 17 19 89.4


line stmt bran cond sub pod time code
1             package VIC::PIC::P16F677;
2 1     1   8 use strict;
  1         3  
  1         26  
3 1     1   4 use warnings;
  1         1  
  1         41  
4             our $VERSION = '0.32';
5             $VERSION = eval $VERSION;
6 1     1   5 use Moo;
  1         2  
  1         3  
7             extends 'VIC::PIC::Base';
8              
9             # role CodeGen
10             has type => (is => 'ro', default => 'p16f677');
11             has include => (is => 'ro', default => 'p16f677.inc');
12              
13             #role Chip
14             has f_osc => (is => 'ro', default => 4e6); # 4MHz internal oscillator
15             has pcl_size => (is => 'ro', default => 13); # program counter (PCL) size
16             has stack_size => (is => 'ro', default => 8); # 8 levels of 13-bit entries
17             has wreg_size => (is => 'ro', default => 8); # 8-bit register WREG
18             # all memory is in bytes
19             has memory => (is => 'ro', default => sub {
20             {
21             flash => 2048, # words
22             SRAM => 128,
23             EEPROM => 256,
24             }
25             });
26             has address => (is => 'ro', default => sub {
27             {
28             isr => [ 0x0004 ],
29             reset => [ 0x0000 ],
30             range => [ 0x0000, 0x07FF ],
31             }
32             });
33              
34             has pin_counts => (is => 'ro', default => sub { {
35             pdip => 20, ## PDIP or DIP ?
36             soic => 20,
37             ssop => 20,
38             total => 20,
39             io => 18,
40             }});
41              
42             has banks => (is => 'ro', default => sub {
43             {
44             count => 4,
45             size => 0x80,
46             gpr => {
47             0 => [ 0x020, 0x07F],
48             1 => [ 0x0A0, 0x0BF],
49             },
50             # remapping of these addresses automatically done by chip
51             common => [0x070, 0x07F],
52             remap => [
53             [0x0F0, 0x0FF],
54             [0x170, 0x17F],
55             [0x1F0, 0x1FF],
56             ],
57             }
58             });
59              
60             has registers => (is => 'ro', default => sub {
61             {
62             INDF => [0x000, 0x080, 0x100, 0x180], # indirect addressing
63             TMR0 => [0x001, 0x101],
64             OPTION_REG => [0x081, 0x181],
65             PCL => [0x002, 0x082, 0x102, 0x182],
66             STATUS => [0x003, 0x083, 0x103, 0x183],
67             FSR => [0x004, 0x084, 0x104, 0x184],
68             PORTA => [0x005, 0x105],
69             TRISA => [0x085, 0x185],
70             PORTB => [0x006, 0x106],
71             TRISB => [0x086, 0x186],
72             PORTC => [0x007, 0x107],
73             TRISC => [0x087, 0x187],
74             PCLATH => [0x00A, 0x08A, 0x10A, 0x18A],
75             INTCON => [0x00B, 0x08B, 0x10B, 0x18B],
76             PIR1 => [0x00C],
77             PIE1 => [0x08C],
78             EEDAT => [0x10C],
79             EECON1 => [0x18C],
80             PIR2 => [0x00D],
81             PIE2 => [0x08D],
82             EEADR => [0x10D],
83             EECON2 => [0x18D], # not addressable apparently
84             TMR1L => [0x00E],
85             PCON => [0x08E],
86             TMR1H => [0x00F],
87             OSCCON => [0x08F],
88             T1CON => [0x010],
89             OSCTUNE => [0x090],
90             T2CON => [0x012],
91             SSPBUF => [0x013],
92             SSPADD => [0x093],
93             SSPCON => [0x014],
94             SSPSTAT => [0x094],
95             WPUA => [0x095],
96             WPUB => [0x115],
97             IOCA => [0x096],
98             IOCB => [0x116],
99             WDTCON => [0x097],
100             VRCON => [0x118],
101             CM1CON0 => [0x119],
102             CM2CON0 => [0x11A],
103             CM2CON1 => [0x11B],
104             ADRESH => [0x01E],
105             ADRESL => [0x09E],
106             ANSEL => [0x11E],
107             SRCON => [0x19E],
108             ADCON0 => [0x01F],
109             ADCON1 => [0x09F],
110             ANSELH => [0x11F],
111             }
112             });
113              
114             has pins => (is => 'ro', default => sub {
115             my $h = {
116             # number to pin name and pin name to number
117             1 => [qw(Vdd)],
118             2 => [qw(RA5 T1CKI OSC1 CLKIN)],
119             3 => [qw(RA4 AN3 T1G OSC2 CLKOUT)],
120             4 => [qw(RA3 MCLR Vpp)],
121             5 => [qw(RC5)],
122             6 => [qw(RC4 C2OUT)],
123             7 => [qw(RC3 AN7 C12IN3-)],
124             8 => [qw(RC6 AN8 SS)],
125             9 => [qw(RC7 AN9 SDO)],
126             10 => [qw(RB7)],
127             11 => [qw(RB6 SCK SCL)],
128             12 => [qw(RB5 AN11)],
129             13 => [qw(RB4 AN10 SDI SDA)],
130             14 => [qw(RC2 AN6 C12IN2-)],
131             15 => [qw(RC1 AN5 C12IN1-)],
132             16 => [qw(RC0 AN4 C2IN+)],
133             17 => [qw(RA2 AN2 T0CKI INT C1OUT)],
134             18 => [qw(RA1 AN1 C12IN0- Vref ICSPCLK)],
135             19 => [qw(RA0 AN0 C1N+ ICSPDAT ULPWU)],
136             20 => [qw(Vss)],
137             };
138             foreach my $k (keys %$h) {
139             my $v = $h->{$k};
140             foreach (@$v) {
141             $h->{$_} = $k;
142             }
143             }
144             return $h;
145             });
146              
147             has clock_pins => (is => 'ro', default => sub {
148             {
149             out => 'CLKOUT',
150             in => 'CLKIN',
151             }
152             });
153              
154             has oscillator_pins => (is => 'ro', default => sub {
155             {
156             1 => 'OSC1',
157             2 => 'OSC2',
158             }
159             });
160              
161             has program_pins => (is => 'ro', default => sub {
162             {
163             clock => 'ICSPCLK',
164             data => 'ICSPDAT',
165             }
166             });
167              
168             has io_ports => (is => 'ro', default => sub {
169             {
170             #port => tristate,
171             PORTA => 'TRISA',
172             PORTB => 'TRISB',
173             PORTC => 'TRISC',
174             }
175             });
176              
177             has input_pins => (is => 'ro', default => sub {
178             {
179             #I/O => [port, tristate, bit]
180             RA0 => ['PORTA', 'TRISA', 0],
181             RA1 => ['PORTA', 'TRISA', 1],
182             RA2 => ['PORTA', 'TRISA', 2],
183             RA3 => ['PORTA', 'TRISA', 3], # input only
184             RA4 => ['PORTA', 'TRISA', 4],
185             RA5 => ['PORTA', 'TRISA', 5],
186             RB4 => ['PORTB', 'TRISB', 4],
187             RB5 => ['PORTB', 'TRISB', 5],
188             RB6 => ['PORTB', 'TRISB', 6],
189             RB7 => ['PORTB', 'TRISB', 7],
190             RC0 => ['PORTC', 'TRISC', 0],
191             RC1 => ['PORTC', 'TRISC', 1],
192             RC2 => ['PORTC', 'TRISC', 2],
193             RC3 => ['PORTC', 'TRISC', 3],
194             RC4 => ['PORTC', 'TRISC', 4],
195             RC5 => ['PORTC', 'TRISC', 5],
196             RC6 => ['PORTC', 'TRISC', 6],
197             RC7 => ['PORTC', 'TRISC', 7],
198             }
199             });
200              
201             has output_pins => (is => 'ro', default => sub {
202             {
203             #I/O => [port, tristate, bit]
204             RA0 => ['PORTA', 'TRISA', 0],
205             RA1 => ['PORTA', 'TRISA', 1],
206             RA2 => ['PORTA', 'TRISA', 2],
207             RA4 => ['PORTA', 'TRISA', 4],
208             RA5 => ['PORTA', 'TRISA', 5],
209             RB4 => ['PORTB', 'TRISB', 4],
210             RB5 => ['PORTB', 'TRISB', 5],
211             RB6 => ['PORTB', 'TRISB', 6],
212             RB7 => ['PORTB', 'TRISB', 7],
213             RC0 => ['PORTC', 'TRISC', 0],
214             RC1 => ['PORTC', 'TRISC', 1],
215             RC2 => ['PORTC', 'TRISC', 2],
216             RC3 => ['PORTC', 'TRISC', 3],
217             RC4 => ['PORTC', 'TRISC', 4],
218             RC5 => ['PORTC', 'TRISC', 5],
219             RC6 => ['PORTC', 'TRISC', 6],
220             RC7 => ['PORTC', 'TRISC', 7],
221             }
222             });
223              
224             has analog_pins => (is => 'ro', default => sub {
225             {
226             # use ANSEL for pins AN0-AN7 and ANSELH for AN8-AN11
227             #pin => number, bit
228             AN0 => [19, 0],
229             AN1 => [18, 1],
230             AN2 => [17, 2],
231             AN3 => [3, 3],
232             AN4 => [16, 4],
233             AN5 => [15, 5],
234             AN6 => [14, 6],
235             AN7 => [ 7, 7],
236             AN8 => [ 8, 8],
237             AN9 => [ 9, 9],
238             AN10 => [13, 10],
239             AN11 => [12, 12],
240             }
241             });
242              
243             has adc_channels => (is => 'ro', default => 12);
244             has adcs_bits => (is => 'ro', default => sub {
245             {
246             2 => '000',
247             4 => '100',
248             8 => '001',
249             16 => '101',
250             32 => '010',
251             64 => '110',
252             internal => '111',
253             }
254             });
255             has adc_chs_bits => (is => 'ro', default => sub {
256             {
257             #pin => chsbits
258             AN0 => '0000',
259             AN1 => '0001',
260             AN2 => '0010',
261             AN3 => '0011',
262             AN4 => '0100',
263             AN5 => '0101',
264             AN6 => '0110',
265             AN7 => '0111',
266             AN8 => '1000',
267             AN9 => '1001',
268             AN10 => '1010',
269             AN11 => '1011',
270             CVref => '1100',
271             '0.6V' => '1101',
272             }
273             });
274              
275             has timer_prescaler => (is => 'ro', default => sub {
276             {
277             2 => '000',
278             4 => '001',
279             8 => '010',
280             16 => '011',
281             32 => '100',
282             64 => '101',
283             128 => '110',
284             256 => '111',
285             }
286             });
287              
288             has wdt_prescaler => (is => 'ro', default => sub {
289             {
290             1 => '000',
291             2 => '001',
292             4 => '010',
293             8 => '011',
294             16 => '100',
295             32 => '101',
296             64 => '110',
297             128 => '111',
298             }
299             });
300              
301             has timer_pins => (is => 'ro', default => sub {
302             {
303             #reg #reg #ireg #flag #enable
304             TMR0 => { reg => 'TMR0', freg => 'INTCON', flag => 'T0IF', enable => 'T0IE', ereg => 'INTCON' },
305             TMR1 => { reg => ['TMR1H', 'TMR1L'], freg => 'PIR1', ereg => 'PIE1', flag => 'TMR1IF', enable => 'TMR1E' },
306             T0CKI => 17,
307             T1CKI => 2,
308             T1G => 3,
309             }
310             });
311              
312             #external interrupt
313             has eint_pins => (is => 'ro', default => sub {
314             {
315             INT => 17,
316             }
317             });
318              
319             has ioc_pins => (is => 'ro', default => sub {
320             {
321             #pin, #ioc-bit #ioc-reg
322             RA0 => [19, 'IOCA0', 'IOCA'],
323             RA1 => [18, 'IOCA1', 'IOCA'],
324             RA2 => [17, 'IOCA2', 'IOCA'],
325             RA3 => [4, 'IOCA3', 'IOCA'],
326             RA4 => [3, 'IOCA4', 'IOCA'],
327             RA5 => [2, 'IOCA5', 'IOCA'],
328             RB4 => [13, 'IOCB4', 'IOCB'],
329             RB5 => [12, 'IOCB5', 'IOCB'],
330             RB6 => [11, 'IOCB6', 'IOCB'],
331             RB7 => [10, 'IOCB7', 'IOCB'],
332             }
333             });
334              
335             has ioc_ports => (is => 'ro', default => sub {
336             {
337             PORTA => 'IOCA',
338             PORTB => 'IOCB',
339             FLAG => 'RABIF',
340             ENABLE => 'RABIE',
341             }
342             });
343              
344             has selector_pins => (is => 'ro', default => sub {
345             {
346             'spi_or_i2c' => 'SS',
347             }
348             });
349              
350             has spi_pins => (is => 'ro', default => sub {
351             {
352             data_out => 'SDO',
353             data_in => 'SDI',
354             clock => 'SCK',
355             }
356             });
357              
358             has i2c_pins => (is => 'ro', default => sub {
359             {
360             data => 'SDA',
361             clock => 'SCL',
362             }
363             });
364              
365             has cmp_input_pins => (is => 'ro', default => sub {
366             {
367             'C1IN+' => 'C1IN+',
368             'C12IN0-' => 'C12IN0-',
369             'C2IN+' => 'C2IN+',
370             'C12IN1-' => 'C12IN1-',
371             'C12IN2-' => 'C12IN2-',
372             'C12IN3-' => 'C12IN3-',
373             }
374             });
375              
376             has cmp_output_pins => (is => 'ro', default => sub {
377             {
378             C1OUT => 'C1OUT',
379             C2OUT => 'C2OUT',
380             }
381             });
382              
383             my @rolenames = qw(CodeGen Operators Chip GPIO ADC ISR Timer Operations SPI I2C
384             Comparator);
385             my @roles = map (("VIC::PIC::Roles::$_", "VIC::PIC::Functions::$_"), @rolenames);
386             with @roles;
387              
388             sub list_roles {
389 1     1 0 1339 my @arr = grep {!/CodeGen|Oper|Chip|ISR/} @rolenames;
  11         26  
390 1 50       15 return wantarray ? @arr : [@arr];
391             }
392              
393             1;
394             __END__