File Coverage

blib/lib/VIC/PIC/P16F627A.pm
Criterion Covered Total %
statement 15 17 88.2
branch 1 2 50.0
condition n/a
subroutine 5 6 83.3
pod 0 2 0.0
total 21 27 77.7


line stmt bran cond sub pod time code
1             package VIC::PIC::P16F627A;
2 1     1   3 use strict;
  1         1  
  1         26  
3 1     1   3 use warnings;
  1         1  
  1         45  
4             our $VERSION = '0.31';
5             $VERSION = eval $VERSION;
6 1     1   3 use Carp;
  1         1  
  1         53  
7 1     1   5 use Moo;
  1         2  
  1         8  
8             extends 'VIC::PIC::Base';
9              
10             # role CodeGen
11             has type => (is => 'ro', default => 'p16f627a');
12             has include => (is => 'ro', default => 'p16f627a.inc');
13              
14             #role Chip
15             has f_osc => (is => 'ro', default => 4e6); # 4MHz internal oscillator
16             has pcl_size => (is => 'ro', default => 13); # program counter (PCL) size
17             has stack_size => (is => 'ro', default => 8); # 8 levels of 13-bit entries
18             has wreg_size => (is => 'ro', default => 8); # 8-bit register WREG
19             # all memory is in bytes
20             has memory => (is => 'ro', default => sub {
21             {
22             flash => 1024, # words
23             SRAM => 224,
24             EEPROM => 128,
25             }
26             });
27             has address => (is => 'ro', default => sub {
28             {
29             isr => [ 0x0004 ],
30             reset => [ 0x0000 ],
31             range => [ 0x0000, 0x03FF ],
32             }
33             });
34              
35             has pin_counts => (is => 'ro', default => sub { {
36             pdip => 18, ## PDIP or DIP ?
37             soic => 20,
38             ssop => 20,
39             qfn => 28,
40             total => 20,
41             io => 16,
42             }});
43              
44             has banks => (is => 'ro', default => sub {
45             {
46             count => 4,
47             size => 0x80,
48             gpr => {
49             0 => [ 0x020, 0x07F],
50             1 => [ 0x0A0, 0x0EF],
51             2 => [ 0x120, 0x14F],
52             },
53             # remapping of these addresses automatically done by chip
54             common => [0x070, 0x07F],
55             remap => [
56             [0x0F0, 0x0FF],
57             [0x170, 0x17F],
58             [0x1F0, 0x1FF],
59             ],
60             }
61             });
62              
63             has registers => (is => 'ro', default => sub {
64             {
65             INDF => [0x000, 0x080, 0x100, 0x180], # indirect addressing
66             TMR0 => [0x001, 0x101],
67             OPTION_REG => [0x081, 0x181],
68             PCL => [0x002, 0x082, 0x102, 0x182],
69             STATUS => [0x003, 0x083, 0x103, 0x183],
70             FSR => [0x004, 0x084, 0x104, 0x184],
71             PORTA => [0x005],
72             TRISA => [0x085],
73             PORTB => [0x006, 0x106],
74             TRISB => [0x086, 0x186],
75             PCLATH => [0x00A, 0x08A, 0x10A, 0x18A],
76             INTCON => [0x00B, 0x08B, 0x10B, 0x18B],
77             PIR1 => [0x00C],
78             PIE1 => [0x08C],
79             TMR1L => [0x00E],
80             PCON => [0x08E],
81             TMR1H => [0x00F],
82             T1CON => [0x010],
83             TMR2 => [0x011],
84             T2CON => [0x012],
85             PR2 => [0x092],
86             CCPR1L => [0x015],
87             CCPR1H => [0x016],
88             CCP1CON => [0x017],
89             RCSTA => [0x018],
90             TXSTA => [0x098],
91             TXREG => [0x019],
92             SPBRG => [0x099],
93             RCREG => [0x01A],
94             EEDATA => [0x09A],
95             EEADR => [0x09B],
96             EECON1 => [0x09C],
97             EECON2 => [0x09D], # not addressable apparently
98             CMCON => [0x01F],
99             VRCON => [0x09F],
100             }
101             });
102              
103             has pins => (is => 'ro', default => sub {
104             my $h = {
105             # number to pin name and pin name to number
106             1 => [qw(RA2 AN2 Vref)],
107             2 => [qw(RA3 AN3 CMP1)],
108             3 => [qw(RA4 T0CKI CMP2)],
109             4 => [qw(RA5 MCLR Vpp)],
110             5 => [qw(Vss)],
111             6 => [qw(RB0 INT)],
112             7 => [qw(RB1 RX DT)],
113             8 => [qw(RB2 TX CK)],
114             9 => [qw(RB3 CCP1)],
115             10 => [qw(RB4 PGM)],
116             11 => [qw(RB5)],
117             12 => [qw(RB6 T1OSO T1CKI PGC)],
118             13 => [qw(RB7 T1OSI PGD)],
119             14 => [qw(Vdd)],
120             15 => [qw(RA6 OSC2 CLKOUT)],
121             16 => [qw(RA7 OSC1 CLKIN)],
122             17 => [qw(RA0 AN0)],
123             18 => [qw(RA1 AN1)],
124             };
125             foreach my $k (keys %$h) {
126             my $v = $h->{$k};
127             foreach (@$v) {
128             $h->{$_} = $k;
129             }
130             }
131             return $h;
132             });
133              
134             has clock_pins => (is => 'ro', default => sub {
135             {
136             out => 'CLKOUT',
137             in => 'CLKIN',
138             }
139             });
140              
141             has oscillator_pins => (is => 'ro', default => sub {
142             {
143             1 => 'OSC1',
144             2 => 'OSC2',
145             }
146             });
147              
148             has program_pins => (is => 'ro', default => sub {
149             {
150             clock => 'PGC',
151             data => 'PGD',
152             enable => 'PGM',
153             }
154             });
155              
156             has io_ports => (is => 'ro', default => sub {
157             {
158             #port => tristate,
159             PORTA => 'TRISA',
160             PORTB => 'TRISB',
161             }
162             });
163              
164             has input_pins => (is => 'ro', default => sub {
165             {
166             #I/O => [port, tristate, bit]
167             RA0 => ['PORTA', 'TRISA', 0],
168             RA1 => ['PORTA', 'TRISA', 1],
169             RA2 => ['PORTA', 'TRISA', 2],
170             RA3 => ['PORTA', 'TRISA', 3],
171             RA4 => ['PORTA', 'TRISA', 4],
172             RA5 => ['PORTA', 'TRISA', 5], # input only
173             RA6 => ['PORTA', 'TRISA', 6],
174             RA7 => ['PORTA', 'TRISA', 7],
175             RB0 => ['PORTB', 'TRISB', 0],
176             RB1 => ['PORTB', 'TRISB', 1],
177             RB2 => ['PORTB', 'TRISB', 2],
178             RB3 => ['PORTB', 'TRISB', 3],
179             RB4 => ['PORTB', 'TRISB', 4],
180             RB5 => ['PORTB', 'TRISB', 5],
181             RB6 => ['PORTB', 'TRISB', 6],
182             RB7 => ['PORTB', 'TRISB', 7],
183             }
184             });
185              
186             has output_pins => (is => 'ro', default => sub {
187             {
188             #I/O => [port, tristate, bit]
189             RA0 => ['PORTA', 'TRISA', 0],
190             RA1 => ['PORTA', 'TRISA', 1],
191             RA2 => ['PORTA', 'TRISA', 2],
192             RA3 => ['PORTA', 'TRISA', 3],
193             RA4 => ['PORTA', 'TRISA', 4],
194             RA6 => ['PORTA', 'TRISA', 6],
195             RA7 => ['PORTA', 'TRISA', 7],
196             RB0 => ['PORTB', 'TRISB', 0],
197             RB1 => ['PORTB', 'TRISB', 1],
198             RB2 => ['PORTB', 'TRISB', 2],
199             RB3 => ['PORTB', 'TRISB', 3],
200             RB4 => ['PORTB', 'TRISB', 4],
201             RB5 => ['PORTB', 'TRISB', 5],
202             RB6 => ['PORTB', 'TRISB', 6],
203             RB7 => ['PORTB', 'TRISB', 7],
204             }
205             });
206              
207             has analog_pins => (is => 'ro', default => sub { {} });
208              
209             has timer_prescaler => (is => 'ro', default => sub {
210             {
211             2 => '000',
212             4 => '001',
213             8 => '010',
214             16 => '011',
215             32 => '100',
216             64 => '101',
217             128 => '110',
218             256 => '111',
219             }
220             });
221              
222             has wdt_prescaler => (is => 'ro', default => sub {
223             {
224             1 => '000',
225             2 => '001',
226             4 => '010',
227             8 => '011',
228             16 => '100',
229             32 => '101',
230             64 => '110',
231             128 => '111',
232             }
233             });
234              
235             has timer_pins => (is => 'ro', default => sub {
236             {
237             TMR0 => { reg => 'TMR0', freg => 'INTCON', flag => 'T0IF', enable => 'T0IE', ereg => 'INTCON' },
238             TMR1 => { reg => ['TMR1H', 'TMR1L'], freg => 'PIR1', ereg => 'PIE1', flag => 'TMR1IF', enable => 'TMR1IE' },
239             TMR2 => { reg => 'TMR2', freg => 'PIR1', flag => 'TMR2IF', ereg => 'PIE1', enable => 'TMR2IF' },
240             # timer 0 clock input
241             T0CKI => 3,
242             # timer 1 clock input
243             T1CKI => 12,
244             # timer oscillator input
245             T1OSI => 13,
246             # timer oscillator output
247             T1OSO => 12,
248             }
249             });
250              
251             has ccp_pins => (is => 'ro', default => sub {
252             {
253             CCP1 => 'CCP1',
254             }
255             });
256              
257             #external interrupt
258             has eint_pins => (is => 'ro', default => sub {
259             {
260             INT => 6,
261             }
262             });
263              
264             has ioc_pins => (is => 'ro', default => sub {
265             {
266             ## there is no special IOC register, so use nothing
267             RB4 => [10],
268             RB5 => [11],
269             RB6 => [12],
270             RB7 => [13],
271             }
272             });
273              
274             has ioc_ports => (is => 'ro', default => sub {
275             {
276             FLAG => 'RBIF',
277             ENABLE => 'RBIE',
278             }
279             });
280              
281             has usart_pins => (is => 'ro', default => sub {
282             {
283             async_in => 'RX',
284             async_out => 'TX',
285             sync_clock => 'CK',
286             sync_data => 'DT',
287             #TODO
288             rx_int => {},
289             tx_int => {},
290             # this defines the port names that the user can use
291             # validly. The port names define whether the user wants to use them in
292             # synchronous or asynchronous mode
293             UART => 'async',
294             USART => 'sync',
295             }
296             });
297              
298             sub usart_baudrates {
299 0     0 0 0 carp "Unimplemented";
300 0         0 return;
301             }
302              
303             has cmp_output_pins => (is => 'ro', default => sub {
304             {
305             CMP1 => 'CMP1',
306             CMP2 => 'CMP2',
307             }
308             });
309              
310             has cmp_input_pins => (is => 'ro', default => sub {
311             {
312             AN0 => 'AN0',
313             AN1 => 'AN1',
314             AN2 => 'AN2',
315             AN3 => 'AN3',
316             }
317             });
318              
319             my @rolenames = qw(CodeGen Operators Chip GPIO ISR Timer Operations CCP USART Comparator);
320             my @roles = map (("VIC::PIC::Roles::$_", "VIC::PIC::Functions::$_"), @rolenames);
321             with @roles;
322              
323             sub list_roles {
324 3     3 0 3074 my @arr = grep {!/CodeGen|Oper|Chip|ISR/} @rolenames;
  30         70  
325 3 50       11 return wantarray ? @arr : [@arr];
326             }
327              
328             1;
329             __END__