00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 extern "C" {
00028
00029 #include <inttypes.h>
00030 #include <stdlib.h>
00031
00032
00033 #undef abs
00034 #include "WConstants.h"
00035
00036
00037
00038
00039 }
00040
00041 #include "Sprite.h"
00042 #include "Matrix.h"
00043
00044
00045
00046
00047
00048
00049 #define REG_NOOP 0x00
00050 #define REG_DIGIT0 0x01
00051 #define REG_DIGIT1 0x02
00052 #define REG_DIGIT2 0x03
00053 #define REG_DIGIT3 0x04
00054 #define REG_DIGIT4 0x05
00055 #define REG_DIGIT5 0x06
00056 #define REG_DIGIT6 0x07
00057 #define REG_DIGIT7 0x08
00058 #define REG_DECODEMODE 0x09
00059 #define REG_INTENSITY 0x0A
00060 #define REG_SCANLIMIT 0x0B
00061 #define REG_SHUTDOWN 0x0C
00062 #define REG_DISPLAYTEST 0x0F
00063
00064
00065
00066
00067
00068 Matrix::Matrix(uint8_t data, uint8_t clock, uint8_t load, uint8_t screens )
00069 {
00070
00071 _pinData = data;
00072 _pinClock = clock;
00073 _pinLoad = load;
00074
00075
00076 pinMode(_pinClock, OUTPUT);
00077 pinMode(_pinData, OUTPUT);
00078 pinMode(_pinLoad, OUTPUT);
00079
00080
00081 _screens = screens;
00082 _buffer = (uint8_t*)calloc(_screens, 64);
00083 _maximumX = (_screens * 8);
00084
00085
00086 clear();
00087 setScanLimit(0x07);
00088 setBrightness(0x0F);
00089 setRegister(REG_SHUTDOWN, 0x01);
00090 setRegister(REG_DECODEMODE, 0x00);
00091 setRegister(REG_DISPLAYTEST, 0x00);
00092 }
00093
00094
00095
00096
00097
00098
00099 void Matrix::putByte(uint8_t data)
00100 {
00101 uint8_t i = 8;
00102 uint8_t mask;
00103 while(i > 0) {
00104 mask = 0x01 << (i - 1);
00105 digitalWrite(_pinClock, LOW);
00106 if (data & mask){
00107 digitalWrite(_pinData, HIGH);
00108 }else{
00109 digitalWrite(_pinData, LOW);
00110 }
00111 digitalWrite(_pinClock, HIGH);
00112 --i;
00113 }
00114 }
00115
00116
00117 void Matrix::setRegister(uint8_t reg, uint8_t data)
00118 {
00119 digitalWrite(_pinLoad, LOW);
00120 for(uint8_t i = 0; i < _screens; ++i){
00121 putByte(reg);
00122 putByte(data);
00123 }
00124 digitalWrite(_pinLoad, HIGH);
00125 digitalWrite(_pinLoad, LOW);
00126 }
00127
00128
00129 void Matrix::syncRow(uint8_t row)
00130 {
00131 if (!_buffer) return;
00132
00133
00134 if (row >= 8) return;
00135 digitalWrite(_pinLoad, LOW);
00136 for(uint8_t i = 0; i < _screens; ++i){
00137 putByte(8 - row);
00138 putByte(_buffer[row + (8 * i)]);
00139 }
00140 digitalWrite(_pinLoad, HIGH);
00141 digitalWrite(_pinLoad, LOW);
00142 }
00143
00144
00145
00146
00147
00148
00149 void Matrix::setScanLimit(uint8_t value)
00150 {
00151 setRegister(REG_SCANLIMIT, value & 0x07);
00152 }
00153
00154
00155 void Matrix::setBrightness(uint8_t value)
00156 {
00157 setRegister(REG_INTENSITY, value & 0x0F);
00158 }
00159
00160
00161
00162
00163
00164 void Matrix::buffer(uint8_t x, uint8_t y, uint8_t value)
00165 {
00166 if (!_buffer) return;
00167
00168
00169 if (x >= _maximumX || y >= 8) return;
00170
00171 uint8_t offset = x;
00172 x %= 8;
00173 offset -= x;
00174
00175
00176 if (x == 0){
00177 x = 8;
00178 }
00179 --x;
00180
00181
00182 if(value){
00183 _buffer[y + offset] |= 0x01 << x;
00184 }else{
00185 _buffer[y + offset] &= ~(0x01 << x);
00186 }
00187 }
00188
00189
00190
00191
00192
00193
00194 void Matrix::write(uint8_t x, uint8_t y, uint8_t value)
00195 {
00196 buffer(x, y, value);
00197
00198
00199 syncRow(y);
00200 }
00201
00202 void Matrix::write(uint8_t x, uint8_t y, Sprite sprite)
00203 {
00204 for (uint8_t i = 0; i < sprite.height(); i++){
00205 for (uint8_t j = 0; j < sprite.width(); j++)
00206 buffer(x + j, y + i, sprite.read(j, i));
00207
00208 syncRow(y + i);
00209 }
00210 }
00211
00212
00213 void Matrix::clear(void)
00214 {
00215 if (!_buffer) return;
00216
00217
00218 for(uint8_t i = 0; i < 8; ++i){
00219 for(uint8_t j = 0; j < _screens; ++j){
00220 _buffer[i + (8 * j)] = 0x00;
00221 }
00222 }
00223
00224
00225 for(uint8_t i = 0; i < 8; ++i){
00226 syncRow(i);
00227 }
00228 }
00229