Bird Techstep / MAX72XX

Fork of MAX72XX by Bird Techstep

Committer:
techstep
Date:
Mon Aug 04 12:11:51 2014 +0000
Revision:
2:8662e8d7d8fa
Parent:
1:dfa1f4cac4c9
Child:
3:2bcf4c5b47d4
MAX72xx; MAX7219/MAX7221 Library; 7 SEGMENT LED; Software SPI use digitalOut

Who changed what in which revision?

UserRevisionLine numberNew contents of line
techstep 0:8bdc990b1b57 1 /*****************************************************************************
techstep 0:8bdc990b1b57 2 * Type : C++
techstep 0:8bdc990b1b57 3 * File : MAX72XX.cpp
techstep 0:8bdc990b1b57 4 * Dec. : MAX7219 & MAX7221 Software SPI library
techstep 0:8bdc990b1b57 5 * Copyright (c) 2013-2014, Bird Techstep, tbird_th@hotmail.com
techstep 2:8662e8d7d8fa 6 *
techstep 1:dfa1f4cac4c9 7 * Remark Original codr from LedControl Library [Arduino]
techstep 2:8662e8d7d8fa 8 *
techstep 0:8bdc990b1b57 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
techstep 0:8bdc990b1b57 10 * of this software and associated documentation files (the "Software"), to deal
techstep 0:8bdc990b1b57 11 * in the Software without restriction, including without limitation the rights
techstep 0:8bdc990b1b57 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
techstep 0:8bdc990b1b57 13 * copies of the Software, and to permit persons to whom the Software is
techstep 0:8bdc990b1b57 14 * furnished to do so, subject to the following conditions:
techstep 0:8bdc990b1b57 15 *
techstep 0:8bdc990b1b57 16 * The above copyright notice and this permission notice shall be included in
techstep 0:8bdc990b1b57 17 * all copies or substantial portions of the Software.
techstep 0:8bdc990b1b57 18 *
techstep 0:8bdc990b1b57 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
techstep 0:8bdc990b1b57 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
techstep 0:8bdc990b1b57 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
techstep 0:8bdc990b1b57 22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
techstep 0:8bdc990b1b57 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
techstep 0:8bdc990b1b57 24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
techstep 0:8bdc990b1b57 25 * THE SOFTWARE.
techstep 0:8bdc990b1b57 26 *****************************************************************************/
techstep 0:8bdc990b1b57 27 #include "mbed.h"
techstep 0:8bdc990b1b57 28 #include "MAX72XX.h"
techstep 0:8bdc990b1b57 29
techstep 0:8bdc990b1b57 30 #define LOW 0
techstep 0:8bdc990b1b57 31 #define HIGH 1
techstep 0:8bdc990b1b57 32
techstep 0:8bdc990b1b57 33 //The opcodes for the MAX7221 and MAX7219
techstep 0:8bdc990b1b57 34 #define OP_NOOP 0x00
techstep 0:8bdc990b1b57 35
techstep 0:8bdc990b1b57 36 #define OP_DIGIT0 0x01
techstep 0:8bdc990b1b57 37 #define OP_DIGIT1 0x02
techstep 0:8bdc990b1b57 38 #define OP_DIGIT2 0x03
techstep 0:8bdc990b1b57 39 #define OP_DIGIT3 0x04
techstep 0:8bdc990b1b57 40 #define OP_DIGIT4 0x05
techstep 0:8bdc990b1b57 41 #define OP_DIGIT5 0x06
techstep 0:8bdc990b1b57 42 #define OP_DIGIT6 0x07
techstep 0:8bdc990b1b57 43 #define OP_DIGIT7 0x08
techstep 0:8bdc990b1b57 44
techstep 0:8bdc990b1b57 45 #define OP_DECODEMODE 0x09 // 0x00 = No decode for digits 7–0
techstep 0:8bdc990b1b57 46 // 0x01 = Code B decode for digit 0, No decode for digits 7–1
techstep 0:8bdc990b1b57 47 // 0x0F = Code B decode for digits 3–0, No decode for digits 7–4
techstep 0:8bdc990b1b57 48 // 0xFF = Code B decode for digits 7–0
techstep 0:8bdc990b1b57 49 #define OP_INTENSITY 0x0A // 1/32..31/32 [0..15]
techstep 0:8bdc990b1b57 50 #define OP_SCANLIMIT 0x0B // 0x00 = Display digit 0
techstep 0:8bdc990b1b57 51 // 0x01 = Display digits 0 1
techstep 0:8bdc990b1b57 52 // 0x02 = Display digits 0 1 2
techstep 0:8bdc990b1b57 53 // 0x03 = Display digits 0 1 2 3
techstep 0:8bdc990b1b57 54 // 0x04 = Display digits 0 1 2 3 4
techstep 0:8bdc990b1b57 55 // 0x05 = Display digits 0 1 2 3 4 5
techstep 0:8bdc990b1b57 56 // 0x06 = Display digits 0 1 2 3 4 5 6
techstep 0:8bdc990b1b57 57 // 0x07 = Display digits 0 1 2 3 4 5 6 7
techstep 0:8bdc990b1b57 58 #define OP_SHUTDOWN 0x0C // 0x00 = Shutdown Mode
techstep 0:8bdc990b1b57 59 // 0x01 = Normal Operation
techstep 0:8bdc990b1b57 60 #define OP_DISPLAYTEST 0x0F // 0x00 = Normal Operation
techstep 0:8bdc990b1b57 61 // 0x01 = Display Test Mode
techstep 0:8bdc990b1b57 62
techstep 0:8bdc990b1b57 63
techstep 0:8bdc990b1b57 64 MAX72XX::MAX72XX(PinName mosi_pin, PinName miso_pin, PinName sclk_pin, PinName cs_pin, int numDevices) :cs(cs_pin) {
techstep 0:8bdc990b1b57 65 mosi = new DigitalOut(mosi_pin);
techstep 0:8bdc990b1b57 66 miso = new DigitalIn(miso_pin);
techstep 0:8bdc990b1b57 67 sclk = new DigitalOut(sclk_pin);
techstep 0:8bdc990b1b57 68 format(8);
techstep 0:8bdc990b1b57 69 frequency();
techstep 0:8bdc990b1b57 70
techstep 0:8bdc990b1b57 71 if(numDevices<=0 || numDevices>8 )
techstep 0:8bdc990b1b57 72 numDevices=8;
techstep 0:8bdc990b1b57 73 maxDevices=numDevices;
techstep 0:8bdc990b1b57 74 cs = 1;
techstep 0:8bdc990b1b57 75 for(int i=0;i<64;i++)
techstep 0:8bdc990b1b57 76 status[i] = 0x00;
techstep 0:8bdc990b1b57 77 for(int i=0;i<maxDevices;i++) {
techstep 0:8bdc990b1b57 78 spiTransfer(i,OP_DISPLAYTEST,0);
techstep 0:8bdc990b1b57 79 //scanlimit is set to max on startup
techstep 0:8bdc990b1b57 80 setScanLimit(i,7);
techstep 0:8bdc990b1b57 81 //decode is done in source
techstep 0:8bdc990b1b57 82 spiTransfer(i,OP_DECODEMODE,0);
techstep 0:8bdc990b1b57 83 clearDisplay(i);
techstep 0:8bdc990b1b57 84 //we go into shutdown-mode on startup
techstep 0:8bdc990b1b57 85 shutdown(i,true);
techstep 0:8bdc990b1b57 86 }
techstep 0:8bdc990b1b57 87 }
techstep 0:8bdc990b1b57 88
techstep 0:8bdc990b1b57 89 MAX72XX::~MAX72XX()
techstep 0:8bdc990b1b57 90 {
techstep 0:8bdc990b1b57 91 delete mosi;
techstep 0:8bdc990b1b57 92 delete miso;
techstep 0:8bdc990b1b57 93 delete sclk;
techstep 0:8bdc990b1b57 94 }
techstep 0:8bdc990b1b57 95
techstep 0:8bdc990b1b57 96 void MAX72XX::frequency(int hz)
techstep 0:8bdc990b1b57 97 {
techstep 0:8bdc990b1b57 98 this->freq = hz;
techstep 0:8bdc990b1b57 99 }
techstep 0:8bdc990b1b57 100
techstep 0:8bdc990b1b57 101 void MAX72XX::format(int bits, int mode)
techstep 0:8bdc990b1b57 102 {
techstep 0:8bdc990b1b57 103 this->bits = bits;
techstep 0:8bdc990b1b57 104 this->mode = mode;
techstep 0:8bdc990b1b57 105 polarity = (mode >> 1) & 1;
techstep 0:8bdc990b1b57 106 phase = mode & 1;
techstep 0:8bdc990b1b57 107 sclk->write(polarity);
techstep 0:8bdc990b1b57 108 }
techstep 0:8bdc990b1b57 109
techstep 0:8bdc990b1b57 110 int MAX72XX::write(int value)
techstep 0:8bdc990b1b57 111 {
techstep 0:8bdc990b1b57 112 int read = 0;
techstep 0:8bdc990b1b57 113 for (int bit = bits-1; bit >= 0; --bit)
techstep 0:8bdc990b1b57 114 {
techstep 0:8bdc990b1b57 115 mosi->write(((value >> bit) & 0x01) != 0);
techstep 0:8bdc990b1b57 116
techstep 0:8bdc990b1b57 117 if (phase == 0)
techstep 0:8bdc990b1b57 118 {
techstep 0:8bdc990b1b57 119 if (miso->read())
techstep 0:8bdc990b1b57 120 read |= (1 << bit);
techstep 0:8bdc990b1b57 121 }
techstep 0:8bdc990b1b57 122
techstep 0:8bdc990b1b57 123 sclk->write(!polarity);
techstep 0:8bdc990b1b57 124
techstep 0:8bdc990b1b57 125 wait(1.0/freq/2);
techstep 0:8bdc990b1b57 126
techstep 0:8bdc990b1b57 127 if (phase == 1)
techstep 0:8bdc990b1b57 128 {
techstep 0:8bdc990b1b57 129 if (miso->read())
techstep 0:8bdc990b1b57 130 read |= (1 << bit);
techstep 0:8bdc990b1b57 131 }
techstep 0:8bdc990b1b57 132
techstep 0:8bdc990b1b57 133 sclk->write(polarity);
techstep 0:8bdc990b1b57 134
techstep 0:8bdc990b1b57 135 wait(1.0/freq/2);
techstep 0:8bdc990b1b57 136 }
techstep 0:8bdc990b1b57 137 return read;
techstep 0:8bdc990b1b57 138 }
techstep 0:8bdc990b1b57 139
techstep 0:8bdc990b1b57 140 void MAX72XX::decodeMode(int addr, uint8_t mode) {
techstep 0:8bdc990b1b57 141 if(addr<0 || addr>=maxDevices)
techstep 0:8bdc990b1b57 142 return;
techstep 0:8bdc990b1b57 143 spiTransfer(addr, OP_DECODEMODE, mode);
techstep 0:8bdc990b1b57 144 }
techstep 0:8bdc990b1b57 145
techstep 0:8bdc990b1b57 146 void MAX72XX::displayTest(int addr, bool status) {
techstep 0:8bdc990b1b57 147 if(addr<0 || addr>=maxDevices)
techstep 0:8bdc990b1b57 148 return;
techstep 0:8bdc990b1b57 149 if(status)
techstep 0:8bdc990b1b57 150 spiTransfer(addr, OP_DISPLAYTEST,1);
techstep 0:8bdc990b1b57 151 else
techstep 0:8bdc990b1b57 152 spiTransfer(addr, OP_DISPLAYTEST,0);
techstep 0:8bdc990b1b57 153 }
techstep 0:8bdc990b1b57 154
techstep 0:8bdc990b1b57 155 void MAX72XX::shutdown(int addr, bool status) {
techstep 0:8bdc990b1b57 156 if(addr<0 || addr>=maxDevices)
techstep 0:8bdc990b1b57 157 return;
techstep 0:8bdc990b1b57 158 if(status)
techstep 0:8bdc990b1b57 159 spiTransfer(addr, OP_SHUTDOWN,0);
techstep 0:8bdc990b1b57 160 else
techstep 0:8bdc990b1b57 161 spiTransfer(addr, OP_SHUTDOWN,1);
techstep 0:8bdc990b1b57 162 }
techstep 0:8bdc990b1b57 163
techstep 0:8bdc990b1b57 164 void MAX72XX::setScanLimit(int addr, int limit) {
techstep 0:8bdc990b1b57 165 if(addr<0 || addr>=maxDevices)
techstep 0:8bdc990b1b57 166 return;
techstep 0:8bdc990b1b57 167 if(limit>=0 || limit<8)
techstep 0:8bdc990b1b57 168 spiTransfer(addr, OP_SCANLIMIT,limit);
techstep 0:8bdc990b1b57 169 }
techstep 0:8bdc990b1b57 170
techstep 0:8bdc990b1b57 171 void MAX72XX::setIntensity(int addr, int intensity) {
techstep 0:8bdc990b1b57 172 if(addr<0 || addr>=maxDevices)
techstep 0:8bdc990b1b57 173 return;
techstep 0:8bdc990b1b57 174 if(intensity>=0 || intensity<16)
techstep 0:8bdc990b1b57 175 spiTransfer(addr, OP_INTENSITY,intensity);
techstep 0:8bdc990b1b57 176 }
techstep 0:8bdc990b1b57 177
techstep 0:8bdc990b1b57 178 void MAX72XX::clearDigit(int addr, int digit) {
techstep 0:8bdc990b1b57 179 int offset;
techstep 0:8bdc990b1b57 180
techstep 0:8bdc990b1b57 181 if(addr<0 || addr>=maxDevices)
techstep 0:8bdc990b1b57 182 return;
techstep 0:8bdc990b1b57 183 //spiTransfer(addr, digit+1,0);
techstep 0:8bdc990b1b57 184 offset = addr*8;
techstep 0:8bdc990b1b57 185 for(int i=0;i<8;i++) {
techstep 0:8bdc990b1b57 186 status[offset+i] = 0;
techstep 0:8bdc990b1b57 187 spiTransfer(addr, digit+1,status[offset+i]);
techstep 0:8bdc990b1b57 188 }
techstep 0:8bdc990b1b57 189 }
techstep 0:8bdc990b1b57 190
techstep 0:8bdc990b1b57 191 void MAX72XX::clearDisplay(int addr) {
techstep 0:8bdc990b1b57 192 int offset;
techstep 0:8bdc990b1b57 193
techstep 0:8bdc990b1b57 194 if(addr<0 || addr>=maxDevices)
techstep 0:8bdc990b1b57 195 return;
techstep 0:8bdc990b1b57 196 offset = addr*8;
techstep 0:8bdc990b1b57 197 for(int i=0;i<8;i++) {
techstep 0:8bdc990b1b57 198 status[offset+i] = 0;
techstep 0:8bdc990b1b57 199 spiTransfer(addr, i+1,status[offset+i]);
techstep 0:8bdc990b1b57 200 }
techstep 0:8bdc990b1b57 201 }
techstep 0:8bdc990b1b57 202
techstep 0:8bdc990b1b57 203 void MAX72XX::setDigit(int addr, int digit, uint8_t value, bool dp) {
techstep 0:8bdc990b1b57 204 int offset;
techstep 0:8bdc990b1b57 205 uint8_t v;
techstep 0:8bdc990b1b57 206
techstep 0:8bdc990b1b57 207 if(addr<0 || addr>=maxDevices)
techstep 0:8bdc990b1b57 208 return;
techstep 0:8bdc990b1b57 209 if(digit<0 || digit>7 || value>15)
techstep 0:8bdc990b1b57 210 return;
techstep 0:8bdc990b1b57 211 offset = addr*8;
techstep 0:8bdc990b1b57 212 v = charTable[value];
techstep 0:8bdc990b1b57 213 if(dp)
techstep 0:8bdc990b1b57 214 v |= 0x80;
techstep 0:8bdc990b1b57 215 status[offset+digit]=v;
techstep 0:8bdc990b1b57 216 spiTransfer(addr, digit+1,v);
techstep 0:8bdc990b1b57 217 }
techstep 0:8bdc990b1b57 218
techstep 0:8bdc990b1b57 219 void MAX72XX::setChar(int addr, int digit, char value, bool dp) {
techstep 0:8bdc990b1b57 220 int offset;
techstep 0:8bdc990b1b57 221 uint8_t index,v;
techstep 0:8bdc990b1b57 222
techstep 0:8bdc990b1b57 223 if(addr<0 || addr>=maxDevices)
techstep 0:8bdc990b1b57 224 return;
techstep 0:8bdc990b1b57 225 if(digit<0 || digit>7)
techstep 0:8bdc990b1b57 226 return;
techstep 0:8bdc990b1b57 227 offset = addr*8;
techstep 0:8bdc990b1b57 228 index = value;
techstep 0:8bdc990b1b57 229 if(index >127) {
techstep 0:8bdc990b1b57 230 //no defined beyond index 127, so we use the space char
techstep 0:8bdc990b1b57 231 index = 32;
techstep 0:8bdc990b1b57 232 }
techstep 0:8bdc990b1b57 233 v = charTable[index];
techstep 0:8bdc990b1b57 234 if(dp)
techstep 0:8bdc990b1b57 235 v |= 0x80;
techstep 0:8bdc990b1b57 236 status[offset+digit] = v;
techstep 0:8bdc990b1b57 237 spiTransfer(addr, digit+1,v);
techstep 0:8bdc990b1b57 238 }
techstep 0:8bdc990b1b57 239
techstep 0:8bdc990b1b57 240 void MAX72XX::spiTransfer(int addr, volatile uint8_t opcode, volatile uint8_t data) {
techstep 0:8bdc990b1b57 241 //Create an array with the data to shift out
techstep 0:8bdc990b1b57 242 int offset = addr*2;
techstep 0:8bdc990b1b57 243 int maxbytes = maxDevices*2;
techstep 0:8bdc990b1b57 244
techstep 0:8bdc990b1b57 245 for(int i=0;i<maxbytes;i++)
techstep 0:8bdc990b1b57 246 spidata[i] = 0;
techstep 0:8bdc990b1b57 247 //put our device data into the array
techstep 0:8bdc990b1b57 248 spidata[offset+1] = opcode;
techstep 0:8bdc990b1b57 249 spidata[offset] = data;
techstep 0:8bdc990b1b57 250 //enable the line
techstep 0:8bdc990b1b57 251 cs = 0;
techstep 0:8bdc990b1b57 252 //Now shift out the data
techstep 0:8bdc990b1b57 253 for(int i=maxbytes;i>0;i--)
techstep 0:8bdc990b1b57 254 this->write(spidata[i-1]);
techstep 0:8bdc990b1b57 255 //latch the data onto the display
techstep 0:8bdc990b1b57 256 cs = 1;
techstep 0:8bdc990b1b57 257 }