2
Matrix.cpp - Max7219 LED Matrix library for Arduino & Wiring
3
Copyright (c) 2006 Nicholas Zambetti. All right reserved.
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Lesser General Public
7
License as published by the Free Software Foundation; either
8
version 2.1 of the License, or (at your option) any later version.
10
This library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Lesser General Public License for more details.
15
You should have received a copy of the GNU Lesser General Public
16
License along with this library; if not, write to the Free Software
17
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
// TODO: Support segment displays in api?
21
// TODO: Support varying vendor layouts?
23
/******************************************************************************
25
******************************************************************************/
32
// Wiring Core Includes
34
#include "WConstants.h"
36
// Wiring Core Prototypes
37
//void pinMode(uint8_t, uint8_t);
38
//void digitalWrite(int, uint8_t);
44
/******************************************************************************
46
******************************************************************************/
50
#define REG_DIGIT0 0x01
51
#define REG_DIGIT1 0x02
52
#define REG_DIGIT2 0x03
53
#define REG_DIGIT3 0x04
54
#define REG_DIGIT4 0x05
55
#define REG_DIGIT5 0x06
56
#define REG_DIGIT6 0x07
57
#define REG_DIGIT7 0x08
58
#define REG_DECODEMODE 0x09
59
#define REG_INTENSITY 0x0A
60
#define REG_SCANLIMIT 0x0B
61
#define REG_SHUTDOWN 0x0C
62
#define REG_DISPLAYTEST 0x0F
64
/******************************************************************************
66
******************************************************************************/
68
Matrix::Matrix(uint8_t data, uint8_t clock, uint8_t load, uint8_t screens /* = 1 */)
70
// record pins for sw spi
75
// set ddr for sw spi pins
76
pinMode(_pinClock, OUTPUT);
77
pinMode(_pinData, OUTPUT);
78
pinMode(_pinLoad, OUTPUT);
80
// allocate screenbuffers
82
_buffer = (uint8_t*)calloc(_screens, 64);
83
_maximumX = (_screens * 8);
85
// initialize registers
86
clear(); // clear display
87
setScanLimit(0x07); // use all rows/digits
88
setBrightness(0x0F); // maximum brightness
89
setRegister(REG_SHUTDOWN, 0x01); // normal operation
90
setRegister(REG_DECODEMODE, 0x00); // pixels not integers
91
setRegister(REG_DISPLAYTEST, 0x00); // not in test mode
94
/******************************************************************************
96
******************************************************************************/
98
// sends a single byte by sw spi (no latching)
99
void Matrix::putByte(uint8_t data)
104
mask = 0x01 << (i - 1); // get bitmask
105
digitalWrite(_pinClock, LOW); // tick
106
if (data & mask){ // choose bit
107
digitalWrite(_pinData, HIGH); // set 1
109
digitalWrite(_pinData, LOW); // set 0
111
digitalWrite(_pinClock, HIGH); // tock
112
--i; // move to lesser bit
116
// sets register to a byte value for all screens
117
void Matrix::setRegister(uint8_t reg, uint8_t data)
119
digitalWrite(_pinLoad, LOW); // begin
120
for(uint8_t i = 0; i < _screens; ++i){
121
putByte(reg); // specify register
122
putByte(data); // send data
124
digitalWrite(_pinLoad, HIGH); // latch in data
125
digitalWrite(_pinLoad, LOW); // end
128
// syncs row of display with buffer
129
void Matrix::syncRow(uint8_t row)
131
if (!_buffer) return;
133
// uint8_t's can't be negative, so don't test for negative row
134
if (row >= 8) return;
135
digitalWrite(_pinLoad, LOW); // begin
136
for(uint8_t i = 0; i < _screens; ++i){
137
putByte(8 - row); // specify register
138
putByte(_buffer[row + (8 * i)]); // send data
140
digitalWrite(_pinLoad, HIGH); // latch in data
141
digitalWrite(_pinLoad, LOW); // end
144
/******************************************************************************
145
* MAX7219 Configuration
146
******************************************************************************/
148
// sets how many digits are displayed
149
void Matrix::setScanLimit(uint8_t value)
151
setRegister(REG_SCANLIMIT, value & 0x07);
154
// sets brightness of the display
155
void Matrix::setBrightness(uint8_t value)
157
setRegister(REG_INTENSITY, value & 0x0F);
160
/******************************************************************************
162
******************************************************************************/
164
void Matrix::buffer(uint8_t x, uint8_t y, uint8_t value)
166
if (!_buffer) return;
168
// uint8_t's can't be negative, so don't test for negative x and y.
169
if (x >= _maximumX || y >= 8) return;
171
uint8_t offset = x; // record x
172
x %= 8; // make x relative to a single matrix
173
offset -= x; // calculate buffer offset
175
// wrap shift relative x for nexus module layout
181
// record value in buffer
183
_buffer[y + offset] |= 0x01 << x;
185
_buffer[y + offset] &= ~(0x01 << x);
189
/******************************************************************************
191
******************************************************************************/
193
// buffers and writes to screen
194
void Matrix::write(uint8_t x, uint8_t y, uint8_t value)
198
// update affected row
202
void Matrix::write(uint8_t x, uint8_t y, Sprite sprite)
204
for (uint8_t i = 0; i < sprite.height(); i++){
205
for (uint8_t j = 0; j < sprite.width(); j++)
206
buffer(x + j, y + i, sprite.read(j, i));
212
// clears screens and buffers
213
void Matrix::clear(void)
215
if (!_buffer) return;
218
for(uint8_t i = 0; i < 8; ++i){
219
for(uint8_t j = 0; j < _screens; ++j){
220
_buffer[i + (8 * j)] = 0x00;
225
for(uint8_t i = 0; i < 8; ++i){