File Coverage

blib/lib/Device/BCM2835/NES.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package Device::BCM2835::NES;
2              
3 1     1   29219 use 5.008005;
  1         4  
  1         32  
4 1     1   6 use strict;
  1         1  
  1         30  
5 1     1   12 use warnings;
  1         10  
  1         27  
6              
7 1     1   4 use Exporter qw(import);
  1         2  
  1         47  
8              
9 0           use Device::BCM2835 qw(
10             BCM2835_GPIO_FSEL_INPT
11             BCM2835_GPIO_FSEL_OUTP
12             RPI_GPIO_P1_03
13             RPI_GPIO_P1_05
14             RPI_GPIO_P1_07
15             RPI_GPIO_P1_08
16             RPI_GPIO_P1_10
17             RPI_GPIO_P1_11
18             RPI_GPIO_P1_12
19             RPI_GPIO_P1_13
20             RPI_GPIO_P1_15
21             RPI_GPIO_P1_16
22             RPI_GPIO_P1_18
23             RPI_GPIO_P1_19
24             RPI_GPIO_P1_21
25             RPI_GPIO_P1_22
26             RPI_GPIO_P1_23
27             RPI_GPIO_P1_24
28             RPI_GPIO_P1_26
29 1     1   387 );
  0            
30              
31             # Button constants
32             use constant {
33             BTN_A => 0x01,
34             BTN_B => 0x02,
35             BTN_SELECT => 0x04,
36             BTN_START => 0x08,
37             BTN_UP => 0x10,
38             BTN_DOWN => 0x20,
39             BTN_LEFT => 0x40,
40             BTN_RIGHT => 0x80
41             };
42              
43             our $VERSION = '0.02';
44             our @EXPORT = ();
45             our %EXPORT_TAGS = (
46             'buttons' => [
47             qw(
48             BTN_A
49             BTN_B
50             BTN_SELECT
51             BTN_START
52             BTN_UP
53             BTN_DOWN
54             BTN_LEFT
55             BTN_RIGHT
56             )
57             ]
58             );
59              
60             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'buttons'} } );
61              
62             # Holds the pin numbers of all controllers added with addController()
63             my $controllers = {};
64              
65             sub new
66             {
67             my $class = shift;
68             my $latch = shift || RPI_GPIO_P1_11;
69             my $clock = shift || RPI_GPIO_P1_12;
70            
71             my $ref = {
72             'latch' => $latch,
73             'clock' => $clock
74             };
75            
76             bless($ref,$class);
77              
78             return $ref;
79             }
80              
81             sub init
82             {
83             my $this = shift;
84              
85             if (!Device::BCM2835::init()) {
86             die("Could not intialize BCM2835 libraries.")
87             }
88              
89             Device::BCM2835::gpio_fsel($this->{latch},BCM2835_GPIO_FSEL_OUTP);
90             Device::BCM2835::gpio_fsel($this->{clock},BCM2835_GPIO_FSEL_OUTP);
91            
92             Device::BCM2835::gpio_clr($this->{latch});
93             Device::BCM2835::gpio_clr($this->{clock});
94              
95             return 1;
96             }
97              
98             sub addController
99             {
100             my $this = shift;
101             my $pin = shift;
102            
103             Device::BCM2835::gpio_fsel($pin,BCM2835_GPIO_FSEL_INPT);
104              
105             push(@{$this->{controllers}},$pin);
106              
107             return 1;
108             }
109              
110             sub read
111             {
112             my $this = shift;
113              
114             # Toggle the latch 12us then wait 6us
115             Device::BCM2835::gpio_set($this->{latch});
116             Device::BCM2835::delayMicroseconds(12);
117             Device::BCM2835::gpio_clr($this->{latch});
118             Device::BCM2835::delayMicroseconds(6);
119              
120             my @value = (); # Will hold value of all buttons.
121             my @tmp = (); # Temporary storage for button data.
122            
123             # Initialize arrays
124             for (my $c = 0; $c < scalar(@{$this->{controllers}}); $c++) {
125             push(@value,0);
126             push(@tmp,0);
127             }
128              
129             # Grab data from all eight buttons by pulsing the clock for 6us (12us for full pulse).
130              
131             for (my $i = 0; $i < 8; $i++) {
132            
133             for (my $c = 0; $c < scalar(@{$this->{controllers}}); $c++) {
134             $tmp[$c] = Device::BCM2835::gpio_lev($this->{controllers}[$c]);
135             }
136              
137             Device::BCM2835::gpio_set($this->{clock});
138             Device::BCM2835::delayMicroseconds(6);
139            
140             Device::BCM2835::gpio_clr($this->{clock});
141             Device::BCM2835::delayMicroseconds(6);
142            
143             for (my $c = 0; $c < scalar(@{$this->{controllers}}); $c++) {
144             $value[$c] |= (!$tmp[$c] << $i);
145             }
146             }
147              
148             return @value;
149             }
150              
151             sub translateButtons
152             {
153             my $this = shift;
154             my $pressed = shift;
155              
156             my @buttons = ();
157              
158             if (($pressed & BTN_A) == BTN_A) {
159             push(@buttons,"A");
160             }
161             if (($pressed & BTN_B) == BTN_B) {
162             push(@buttons,"B");
163             }
164             if (($pressed & BTN_SELECT) == BTN_SELECT) {
165             push(@buttons,"SELECT");
166             }
167             if (($pressed & BTN_START) == BTN_START) {
168             push(@buttons,"START");
169             }
170             if (($pressed & BTN_UP) == BTN_UP) {
171             push(@buttons,"UP");
172             }
173             if (($pressed & BTN_DOWN) == BTN_DOWN) {
174             push(@buttons,"DOWN");
175             }
176             if (($pressed & BTN_LEFT) == BTN_LEFT) {
177             push(@buttons,"LEFT");
178             }
179             if (($pressed & BTN_RIGHT) == BTN_RIGHT) {
180             push(@buttons,"RIGHT");
181             }
182              
183             return @buttons;
184             }
185              
186             sub cycle
187             {
188             my $this = shift;
189             my $time = shift || ((1 / 60) * 1000);
190            
191             Device::BCM2835::delay($time);
192             }
193              
194             1;
195             __END__