File Coverage

blib/lib/HiPi/Interface/MAX7219.pm
Criterion Covered Total %
statement 15 71 21.1
branch 0 14 0.0
condition 0 9 0.0
subroutine 5 17 29.4
pod 0 11 0.0
total 20 122 16.3


line stmt bran cond sub pod time code
1             #########################################################################################
2             # Package HiPi::Interface::MAX7219
3             # Description : Interface to MAX7219 matrix LED driver
4             # Copyright : Copyright (c) 2018 Mark Dootson
5             # License : This is free software; you can redistribute it and/or modify it under
6             # the same terms as the Perl 5 programming language system itself.
7             #########################################################################################
8              
9             package HiPi::Interface::MAX7219;
10              
11             #########################################################################################
12              
13 1     1   1267 use strict;
  1         3  
  1         33  
14 1     1   6 use warnings;
  1         2  
  1         34  
15 1     1   5 use parent qw( HiPi::Interface );
  1         3  
  1         8  
16 1     1   63 use HiPi qw( :max7219 );
  1         2  
  1         172  
17 1     1   7 use HiPi::Device::SPI;
  1         3  
  1         726  
18              
19             our $VERSION ='0.80';
20              
21             __PACKAGE__->create_accessors( qw( ) );
22              
23             my $codefont = {
24             '0' => 0b0000,
25             '1' => 0b0001,
26             '2' => 0b0010,
27             '3' => 0b0011,
28             '4' => 0b0100,
29             '5' => 0b0101,
30             '6' => 0b0110,
31             '7' => 0b0111,
32             '8' => 0b1000,
33             '9' => 0b1001,
34             '-' => 0b1010,
35             'E' => 0b1011,
36             'H' => 0b1100,
37             'L' => 0b1101,
38             'P' => 0b1110,
39             ' ' => 0b1111,
40             };
41              
42             sub _get_code_char {
43 0     0     my $char = shift;
44 0 0         return ( exists($codefont->{$char}) ) ? $codefont->{$char} : $codefont->{' '};
45             }
46              
47             sub new {
48 0     0 0   my ($class, %userparams) = @_;
49            
50 0           my %params = (
51             devicename => '/dev/spidev0.0',
52             speed => 9600000, # 9.6 mhz
53             delay => 0,
54             );
55            
56             # get user params
57 0           foreach my $key( keys (%userparams) ) {
58 0           $params{$key} = $userparams{$key};
59             }
60            
61 0 0         unless(defined($params{device})) {
62             $params{device} = HiPi::Device::SPI->new(
63             speed => $params{speed},
64             delay => $params{delay},
65             devicename => $params{devicename},
66 0           );
67             }
68            
69 0           my $self = $class->SUPER::new(%params);
70            
71 0           $self->set_display_test( 0 );
72            
73 0           return $self;
74             }
75              
76             sub write_code_char {
77 0     0 0   my($self, $matrix, $char, $flags, $cascade) = @_;
78 0   0       $flags //= 0x00;
79 0   0       $char //= ' ';
80 0           my $byte = _get_code_char( $char );
81            
82 0 0         if( $flags & MAX7219_FLAG_DECIMAL ) {
83 0           $byte |= 0x80;
84             }
85            
86 0           $self->send_segment_matrix( $matrix, $byte, $cascade );
87 0           $self->sleep_milliseconds(10);
88             }
89              
90             sub send_segment_matrix {
91             # send data for single matrix
92 0     0 0   my($self, $matrix, $byte, $cascade) = @_;
93 0 0 0       return unless($matrix >= 0 && $matrix < 8 );
94 0           my $reg = MAX7219_REG_DIGIT_0 + $matrix;
95 0           $self->send_command( $reg, $byte, $cascade );
96             }
97              
98             sub send_command {
99 0     0 0   my($self, $register, $data, $cascade ) = @_;
100 0   0       $cascade ||= 0;
101 0           my @bytes = ( $register, $data );
102 0 0         if( $cascade ) {
103 0           for (my $i = 0; $i < $cascade; $i ++ ) {
104 0           push( @bytes, MAX7219_REG_NOOP, 0x00 );
105             }
106             }
107 0           $self->device->transfer_byte_array( @bytes );
108 0           return;
109             }
110              
111             sub send_raw_bytes {
112 0     0 0   my($self, @bytes) = @_;
113 0           $self->device->transfer_byte_array( @bytes );
114 0           return;
115             }
116              
117             sub set_decode_mode {
118 0     0 0   my($self, $mode, $cascade ) = @_;
119             # only covers all on or all off
120             # see data sheet for mixed settings
121 0 0         $mode = ( $mode ) ? 0xFF : 0x00;
122 0           $self->send_command( MAX7219_REG_DECODE_MODE, $mode, $cascade );
123 0           return;
124             }
125              
126             sub set_intensity {
127 0     0 0   my($self, $value, $cascade ) = @_;
128             # value between 0 ( min ) and 15 ( max )
129 0           $value &= 0xF;
130 0           $self->send_command( MAX7219_REG_INTENSITY, $value, $cascade );
131 0           return;
132             }
133              
134             sub set_scan_limit {
135 0     0 0   my($self, $value, $cascade ) = @_;
136             # value between 0 and 7 - how many registers are scanned
137 0           $value &= 0x7;
138 0           $self->send_command( MAX7219_REG_SCAN_LIMIT, $value, $cascade );
139 0           return;
140             }
141              
142             sub shutdown {
143 0     0 0   my($self, $cascade ) = @_;
144 0           $self->send_command( MAX7219_REG_SHUTDOWN, 0x00, $cascade );
145 0           return;
146             }
147              
148             sub wake_up {
149 0     0 0   my($self, $cascade ) = @_;
150 0           $self->send_command( MAX7219_REG_SHUTDOWN, 0x01, $cascade );
151 0           return;
152             }
153              
154             sub set_display_test {
155 0     0 0   my( $self, $testmode, $cascade ) = @_;
156 0 0         $testmode = ( $testmode ) ? 0x01 : 0x00;
157 0           $self->send_command( MAX7219_REG_TEST, $testmode, $cascade );
158 0           $self->sleep_milliseconds(10);
159             }
160              
161             1;
162              
163             __END__