Forked LEDMatrix and added horizontal scrolling

Fork of LEDMatrix by Yihui Xiong

Committer:
Bobty
Date:
Fri Jan 15 12:18:34 2016 +0000
Revision:
5:334fc002e200
Parent:
4:40d4afefcd74
Cleared inversion on clear(); Changed setAlert to setHighlight

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yihui 0:13728deac7a7 1 /**
yihui 0:13728deac7a7 2 * LED Matrix library for http://www.seeedstudio.com/depot/ultrathin-16x32-red-led-matrix-panel-p-1582.html
yihui 0:13728deac7a7 3 * The LED Matrix panel has 32x16 pixels. Several panel can be combined together as a large screen.
yihui 0:13728deac7a7 4 *
yihui 0:13728deac7a7 5 * Coordinate & Connection (mbed -> panel 0 -> panel 1 -> ...)
yihui 0:13728deac7a7 6 * (0, 0) (0, 0)
yihui 0:13728deac7a7 7 * +--------+--------+--------+ +--------+--------+
yihui 0:13728deac7a7 8 * | 5 | 3 | 1 | | 1 | 0 |
yihui 0:13728deac7a7 9 * | | | | | | |<----- mbed
yihui 0:13728deac7a7 10 * +--------+--------+--------+ +--------+--------+
yihui 0:13728deac7a7 11 * | 4 | 2 | 0 | (64, 16)
yihui 0:13728deac7a7 12 * | | | |<----- mbed
yihui 0:13728deac7a7 13 * +--------+--------+--------+
yihui 0:13728deac7a7 14 * (96, 32)
yihui 0:13728deac7a7 15 * Copyright (c) 2013 Seeed Technology Inc.
yihui 0:13728deac7a7 16 * @auther Yihui Xiong
yihui 0:13728deac7a7 17 * @date Nov 8, 2013
yihui 0:13728deac7a7 18 * @license Apache
Bobty 2:cd2da920cf98 19 *
Bobty 2:cd2da920cf98 20 * Heavily modified by Rob Dobson, 2016
yihui 0:13728deac7a7 21 */
yihui 0:13728deac7a7 22
yihui 0:13728deac7a7 23 #include "LEDMatrix.h"
yihui 0:13728deac7a7 24 #include "mbed.h"
Bobty 2:cd2da920cf98 25 #include "fontBig.h"
Bobty 2:cd2da920cf98 26 #include "font5x7.h"
yihui 0:13728deac7a7 27
yihui 0:13728deac7a7 28 #if 0
yihui 0:13728deac7a7 29 #define ASSERT(e) if (!(e)) { Serial.println(#e); while (1); }
yihui 0:13728deac7a7 30 #else
yihui 0:13728deac7a7 31 #define ASSERT(e)
yihui 0:13728deac7a7 32 #endif
yihui 0:13728deac7a7 33
yihui 0:13728deac7a7 34 LEDMatrix::LEDMatrix(PinName pinA, PinName pinB, PinName pinC, PinName pinD, PinName pinOE, PinName pinR1, PinName pinSTB, PinName pinCLK) :
yihui 0:13728deac7a7 35 a(pinA), b(pinB), c(pinC), d(pinD), oe(pinOE), r1(pinR1), stb(pinSTB), clk(pinCLK)
yihui 0:13728deac7a7 36 {
yihui 0:13728deac7a7 37 this->clk = clk;
yihui 0:13728deac7a7 38 this->r1 = r1;
yihui 0:13728deac7a7 39 this->stb = stb;
yihui 0:13728deac7a7 40 this->oe = oe;
yihui 0:13728deac7a7 41 this->a = a;
yihui 0:13728deac7a7 42 this->b = b;
yihui 0:13728deac7a7 43 this->c = c;
yihui 0:13728deac7a7 44 this->d = d;
yihui 0:13728deac7a7 45
yihui 0:13728deac7a7 46 mask = 0xff;
Bobty 2:cd2da920cf98 47 _isEnabled = false;
Bobty 2:cd2da920cf98 48 for (int i = 0; i < LED_MATRIX_LEDS_VERTICALLY; i++)
Bobty 2:cd2da920cf98 49 {
Bobty 2:cd2da920cf98 50 _hScrollPos[i] = 0;
Bobty 2:cd2da920cf98 51 _hScrollWidth[i] = LED_MATRIX_LEDS_HORIZONTALLY;
Bobty 2:cd2da920cf98 52 }
Bobty 2:cd2da920cf98 53 for (int i = 0; i < LED_MATRIX_MAX_LINES; i++)
Bobty 2:cd2da920cf98 54 {
Bobty 2:cd2da920cf98 55 _lineScrollInc[i] = 0;
Bobty 5:334fc002e200 56 _lineHighlight[i] = false;
Bobty 3:1e06e89bc0c9 57 _lineInvert[i] = false;
Bobty 2:cd2da920cf98 58 }
Bobty 2:cd2da920cf98 59 _isBusy = false;
Bobty 2:cd2da920cf98 60 _charSeparation = 1;
Bobty 3:1e06e89bc0c9 61 _flashCounter = 0;
Bobty 4:40d4afefcd74 62 _flashRate = 50;
Bobty 3:1e06e89bc0c9 63 _flashState = false;
Bobty 4:40d4afefcd74 64 _scrollCounter = 0;
Bobty 4:40d4afefcd74 65 _scrollRate = 7;
yihui 0:13728deac7a7 66 }
yihui 0:13728deac7a7 67
Bobty 3:1e06e89bc0c9 68 void LEDMatrix::begin(uint8_t *_pDisplayBuf, uint16_t width, uint16_t height, uint16_t dispBufWidth,
Bobty 4:40d4afefcd74 69 uint16_t numLines, int charSeparation, int flashRate, int scrollRate)
yihui 0:13728deac7a7 70 {
Bobty 2:cd2da920cf98 71 ASSERT(0 == (width % LED_MATRIX_LEDS_HORIZONTALLY));
Bobty 2:cd2da920cf98 72 ASSERT(0 == (scroll_width % LED_MATRIX_LEDS_HORIZONTALLY));
Bobty 2:cd2da920cf98 73 ASSERT(0 == (height % LED_MATRIX_LEDS_VERTICALLY));
yihui 0:13728deac7a7 74
Bobty 2:cd2da920cf98 75 this->_pDisplayBuf = _pDisplayBuf;
yihui 0:13728deac7a7 76 this->width = width;
yihui 0:13728deac7a7 77 this->height = height;
Bobty 2:cd2da920cf98 78 this->dispBufWidth = dispBufWidth;
Bobty 2:cd2da920cf98 79 this->numLines = numLines;
Bobty 2:cd2da920cf98 80 this->_charSeparation = charSeparation;
Bobty 4:40d4afefcd74 81 if (flashRate > 0)
Bobty 4:40d4afefcd74 82 this->_flashRate = flashRate;
Bobty 4:40d4afefcd74 83 if (scrollRate > 0)
Bobty 4:40d4afefcd74 84 this->_scrollRate = scrollRate;
Bobty 2:cd2da920cf98 85 if (numLines > LED_MATRIX_MAX_LINES)
Bobty 2:cd2da920cf98 86 this->numLines = LED_MATRIX_MAX_LINES;
Bobty 2:cd2da920cf98 87 for (int i = 0; i < LED_MATRIX_LEDS_VERTICALLY; i++)
Bobty 2:cd2da920cf98 88 {
Bobty 2:cd2da920cf98 89 this->_hScrollWidth[i] = dispBufWidth;
Bobty 2:cd2da920cf98 90 }
yihui 0:13728deac7a7 91
Bobty 2:cd2da920cf98 92 _isEnabled = true;
yihui 0:13728deac7a7 93 }
yihui 0:13728deac7a7 94
yihui 0:13728deac7a7 95 void LEDMatrix::drawPoint(uint16_t x, uint16_t y, uint8_t pixel)
yihui 0:13728deac7a7 96 {
Bobty 2:cd2da920cf98 97 ASSERT(dispBufWidth > x);
yihui 0:13728deac7a7 98 ASSERT(height > y);
yihui 0:13728deac7a7 99
Bobty 2:cd2da920cf98 100 uint8_t *byte = _pDisplayBuf + (height - 1 - y) * dispBufWidth / 8 + x / 8;
Bobty 2:cd2da920cf98 101 uint8_t bit = x % 8;
yihui 0:13728deac7a7 102
Bobty 2:cd2da920cf98 103 if (pixel)
Bobty 2:cd2da920cf98 104 {
yihui 0:13728deac7a7 105 *byte |= 0x80 >> bit;
Bobty 2:cd2da920cf98 106 }
Bobty 2:cd2da920cf98 107 else
Bobty 2:cd2da920cf98 108 {
yihui 0:13728deac7a7 109 *byte &= ~(0x80 >> bit);
yihui 0:13728deac7a7 110 }
yihui 0:13728deac7a7 111 }
yihui 0:13728deac7a7 112
yihui 0:13728deac7a7 113 void LEDMatrix::drawRect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t pixel)
yihui 0:13728deac7a7 114 {
Bobty 2:cd2da920cf98 115 for (uint16_t x = x1; x < x2; x++)
Bobty 2:cd2da920cf98 116 {
Bobty 2:cd2da920cf98 117 for (uint16_t y = y1; y < y2; y++)
Bobty 2:cd2da920cf98 118 {
yihui 0:13728deac7a7 119 drawPoint(x, y, pixel);
yihui 0:13728deac7a7 120 }
yihui 0:13728deac7a7 121 }
yihui 0:13728deac7a7 122 }
yihui 0:13728deac7a7 123
yihui 0:13728deac7a7 124 void LEDMatrix::drawImage(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t *image)
yihui 0:13728deac7a7 125 {
yihui 0:13728deac7a7 126 ASSERT(0 == ((x2 - x1) % 8));
yihui 0:13728deac7a7 127
Bobty 2:cd2da920cf98 128 for (uint16_t x = x1; x < x2; x++)
Bobty 2:cd2da920cf98 129 {
Bobty 2:cd2da920cf98 130 for (uint16_t y = y1; y < y2; y++)
Bobty 2:cd2da920cf98 131 {
yihui 0:13728deac7a7 132 uint8_t *byte = image + x * 8 + y / 8;
yihui 0:13728deac7a7 133 uint8_t bit = 7 - (y % 8);
yihui 0:13728deac7a7 134 uint8_t pixel = (*byte >> bit) & 1;
yihui 0:13728deac7a7 135 drawPoint(x, y, pixel);
yihui 0:13728deac7a7 136 }
yihui 0:13728deac7a7 137 }
yihui 0:13728deac7a7 138 }
yihui 0:13728deac7a7 139
Bobty 2:cd2da920cf98 140 //void LEDMatrix::clear()
Bobty 2:cd2da920cf98 141 //{
Bobty 2:cd2da920cf98 142 // uint8_t *ptr = _pDisplayBuf;
Bobty 2:cd2da920cf98 143 // for (uint16_t i = 0; i < (dispBufWidth * height / 8); i++)
Bobty 2:cd2da920cf98 144 // {
Bobty 2:cd2da920cf98 145 // *ptr = 0x00;
Bobty 2:cd2da920cf98 146 // ptr++;
Bobty 2:cd2da920cf98 147 // }
Bobty 2:cd2da920cf98 148 //}
yihui 0:13728deac7a7 149
Bobty 2:cd2da920cf98 150 void LEDMatrix::invertColour()
yihui 0:13728deac7a7 151 {
yihui 0:13728deac7a7 152 mask = ~mask;
yihui 0:13728deac7a7 153 }
yihui 0:13728deac7a7 154
Bobty 2:cd2da920cf98 155 uint8_t LEDMatrix::isInvertedColour()
yihui 0:13728deac7a7 156 {
yihui 0:13728deac7a7 157 return mask;
yihui 0:13728deac7a7 158 }
yihui 0:13728deac7a7 159
yihui 0:13728deac7a7 160 void LEDMatrix::scan()
yihui 0:13728deac7a7 161 {
Bobty 2:cd2da920cf98 162 // On each call this function handles one row of the display
Bobty 2:cd2da920cf98 163 static uint8_t scanRowIdx = 0;
yihui 0:13728deac7a7 164
Bobty 2:cd2da920cf98 165 // Check if being updated
Bobty 2:cd2da920cf98 166 if (_isBusy)
yihui 0:13728deac7a7 167 return;
Bobty 2:cd2da920cf98 168
Bobty 2:cd2da920cf98 169 // Check if display enabled
Bobty 2:cd2da920cf98 170 if (!_isEnabled)
Bobty 2:cd2da920cf98 171 return;
yihui 0:13728deac7a7 172
Bobty 2:cd2da920cf98 173 // Base of this scan row in buffer to display
Bobty 2:cd2da920cf98 174 uint8_t *pBufBase = _pDisplayBuf + scanRowIdx * (dispBufWidth / 8);
Bobty 2:cd2da920cf98 175
Bobty 2:cd2da920cf98 176 // Handle multiple units vertically
Bobty 2:cd2da920cf98 177 for (int rowIdx = 0; rowIdx < (height / LED_MATRIX_LEDS_VERTICALLY); rowIdx++)
Bobty 1:79cf2e115449 178 {
Bobty 2:cd2da920cf98 179 // Calculate buffer position within this unit
Bobty 2:cd2da920cf98 180 uint8_t *pBuf = pBufBase + rowIdx * (dispBufWidth / 8) * LED_MATRIX_LEDS_VERTICALLY;
yihui 0:13728deac7a7 181
Bobty 3:1e06e89bc0c9 182 // Work out which display line we're in
Bobty 3:1e06e89bc0c9 183 uint8_t dispMask = mask;
Bobty 3:1e06e89bc0c9 184 int rowsInLine = (height/numLines);
Bobty 3:1e06e89bc0c9 185 int dispLine = scanRowIdx / rowsInLine;
Bobty 3:1e06e89bc0c9 186 if (dispLine < numLines)
Bobty 3:1e06e89bc0c9 187 {
Bobty 3:1e06e89bc0c9 188 if (_lineInvert[dispLine])
Bobty 3:1e06e89bc0c9 189 dispMask = ~dispMask;
Bobty 3:1e06e89bc0c9 190 }
Bobty 3:1e06e89bc0c9 191
Bobty 2:cd2da920cf98 192 // Work along the display row sending out data as we go
Bobty 2:cd2da920cf98 193 // Noting that the first data we send out will be shunted to the end of the row
Bobty 2:cd2da920cf98 194 int hScrollPos = _hScrollPos[scanRowIdx];
Bobty 2:cd2da920cf98 195 int hScrollWidth = _hScrollWidth[scanRowIdx];
Bobty 2:cd2da920cf98 196 if (hScrollWidth > dispBufWidth)
Bobty 2:cd2da920cf98 197 hScrollWidth = dispBufWidth;
Bobty 2:cd2da920cf98 198 int bitOffset = hScrollPos % 8;
Bobty 2:cd2da920cf98 199 for (int byteIdx = (width / 8) - 1; byteIdx >= 0; byteIdx--)
Bobty 1:79cf2e115449 200 {
Bobty 2:cd2da920cf98 201 // When a row is scrolled a single byte on the display can be a combination of two buffer bytes
Bobty 2:cd2da920cf98 202 uint8_t* pByte1 = pBuf + ((byteIdx*8 + hScrollPos) % hScrollWidth) / 8;
Bobty 2:cd2da920cf98 203 uint8_t* pByte2 = pBuf + (((byteIdx+1)*8 + hScrollPos) % hScrollWidth) / 8;
Bobty 2:cd2da920cf98 204 uint8_t pixels = ((*pByte1) << bitOffset) + (((*pByte2) >> (8 - bitOffset)) % 256);
Bobty 2:cd2da920cf98 205
Bobty 2:cd2da920cf98 206 // Reverse the bits so they come out in the right order
Bobty 3:1e06e89bc0c9 207 pixels = reverseBits(pixels) ^ dispMask; // reverse: mask = 0xff, normal: mask =0x00
Bobty 1:79cf2e115449 208 for (uint8_t bit = 0; bit < 8; bit++)
Bobty 1:79cf2e115449 209 {
yihui 0:13728deac7a7 210 clk = 0;
yihui 0:13728deac7a7 211 r1 = pixels & (0x80 >> bit);
yihui 0:13728deac7a7 212 clk = 1;
yihui 0:13728deac7a7 213 }
yihui 0:13728deac7a7 214 }
yihui 0:13728deac7a7 215 }
yihui 0:13728deac7a7 216
Bobty 2:cd2da920cf98 217 // Disable display
Bobty 2:cd2da920cf98 218 oe = 1;
yihui 0:13728deac7a7 219
Bobty 2:cd2da920cf98 220 // Select row (rows are muxed)
Bobty 2:cd2da920cf98 221 int rowSel = LED_MATRIX_LEDS_VERTICALLY - 1 - scanRowIdx;
Bobty 2:cd2da920cf98 222 a = (rowSel & 0x01);
Bobty 2:cd2da920cf98 223 b = (rowSel & 0x02);
Bobty 2:cd2da920cf98 224 c = (rowSel & 0x04);
Bobty 2:cd2da920cf98 225 d = (rowSel & 0x08);
yihui 0:13728deac7a7 226
Bobty 2:cd2da920cf98 227 // Latch data
yihui 0:13728deac7a7 228 stb = 0;
yihui 0:13728deac7a7 229 stb = 1;
yihui 0:13728deac7a7 230
Bobty 2:cd2da920cf98 231 // Reenable display
Bobty 2:cd2da920cf98 232 oe = 0;
yihui 0:13728deac7a7 233
Bobty 2:cd2da920cf98 234 // Move the scan row on for next time
Bobty 2:cd2da920cf98 235 scanRowIdx = (scanRowIdx + 1) & 0x0F;
yihui 0:13728deac7a7 236 }
yihui 0:13728deac7a7 237
yihui 0:13728deac7a7 238 void LEDMatrix::on()
yihui 0:13728deac7a7 239 {
Bobty 2:cd2da920cf98 240 _isEnabled = true;
yihui 0:13728deac7a7 241 }
yihui 0:13728deac7a7 242
yihui 0:13728deac7a7 243 void LEDMatrix::off()
yihui 0:13728deac7a7 244 {
Bobty 2:cd2da920cf98 245 _isEnabled = false;
yihui 0:13728deac7a7 246 oe = 1;
yihui 0:13728deac7a7 247 }
yihui 0:13728deac7a7 248
Bobty 2:cd2da920cf98 249 bool LEDMatrix::getRowsToWorkOn(int lineIdx, int &startRow, int &numRows)
Bobty 2:cd2da920cf98 250 {
Bobty 2:cd2da920cf98 251 // lineIdx == -1 means all lines
Bobty 2:cd2da920cf98 252 startRow = 0;
Bobty 2:cd2da920cf98 253 numRows = LED_MATRIX_LEDS_VERTICALLY;
Bobty 2:cd2da920cf98 254 if (lineIdx != -1)
Bobty 2:cd2da920cf98 255 {
Bobty 2:cd2da920cf98 256 if ((lineIdx < 0) || (lineIdx >= numLines))
Bobty 2:cd2da920cf98 257 return false;
Bobty 2:cd2da920cf98 258 numRows = height / numLines;
Bobty 2:cd2da920cf98 259 startRow = lineIdx * numRows;
Bobty 2:cd2da920cf98 260 }
Bobty 2:cd2da920cf98 261 return true;
Bobty 2:cd2da920cf98 262 }
Bobty 2:cd2da920cf98 263
Bobty 2:cd2da920cf98 264 void LEDMatrix::scrollReset(int lineIdx)
Bobty 2:cd2da920cf98 265 {
Bobty 2:cd2da920cf98 266 // Interpret param
Bobty 2:cd2da920cf98 267 int startRow = 0;
Bobty 2:cd2da920cf98 268 int numRows = LED_MATRIX_LEDS_VERTICALLY;
Bobty 2:cd2da920cf98 269 if (!getRowsToWorkOn(lineIdx, startRow, numRows))
Bobty 2:cd2da920cf98 270 return;
Bobty 2:cd2da920cf98 271 // Reset scroll position all rows
Bobty 2:cd2da920cf98 272 for (int i = startRow; i < startRow+numRows; i++)
Bobty 2:cd2da920cf98 273 _hScrollPos[i] = 0;
Bobty 2:cd2da920cf98 274 }
Bobty 2:cd2da920cf98 275
Bobty 2:cd2da920cf98 276 void LEDMatrix::scroll(int lineIdx, bool scrollLeft)
Bobty 2:cd2da920cf98 277 {
Bobty 2:cd2da920cf98 278 // Interpret param
Bobty 2:cd2da920cf98 279 int startRow = 0;
Bobty 2:cd2da920cf98 280 int numRows = LED_MATRIX_LEDS_VERTICALLY;
Bobty 2:cd2da920cf98 281 if (!getRowsToWorkOn(lineIdx, startRow, numRows))
Bobty 2:cd2da920cf98 282 return;
Bobty 2:cd2da920cf98 283 // Reset scroll position all rows
Bobty 2:cd2da920cf98 284 for (int i = startRow; i < startRow+numRows; i++)
Bobty 2:cd2da920cf98 285 {
Bobty 2:cd2da920cf98 286 if (scrollLeft)
Bobty 2:cd2da920cf98 287 {
Bobty 2:cd2da920cf98 288 _hScrollPos[i]++;
Bobty 2:cd2da920cf98 289 if (_hScrollPos[i] >= _hScrollWidth[i])
Bobty 2:cd2da920cf98 290 _hScrollPos[i] = 0;
Bobty 2:cd2da920cf98 291 }
Bobty 2:cd2da920cf98 292 else
Bobty 2:cd2da920cf98 293 {
Bobty 2:cd2da920cf98 294 _hScrollPos[i]--;
Bobty 2:cd2da920cf98 295 if (_hScrollPos[i] < 0)
Bobty 2:cd2da920cf98 296 _hScrollPos[i] = _hScrollWidth[i]-1;
Bobty 2:cd2da920cf98 297 }
Bobty 2:cd2da920cf98 298 }
Bobty 2:cd2da920cf98 299 }
Bobty 2:cd2da920cf98 300
Bobty 2:cd2da920cf98 301 void LEDMatrix::scrollToPos(int lineIdx, int pos)
Bobty 1:79cf2e115449 302 {
Bobty 2:cd2da920cf98 303 // Interpret param
Bobty 2:cd2da920cf98 304 int startRow = 0;
Bobty 2:cd2da920cf98 305 int numRows = LED_MATRIX_LEDS_VERTICALLY;
Bobty 2:cd2da920cf98 306 if (!getRowsToWorkOn(lineIdx, startRow, numRows))
Bobty 2:cd2da920cf98 307 return;
Bobty 2:cd2da920cf98 308 // Check pos
Bobty 2:cd2da920cf98 309 if ((pos < 0) || (pos >= dispBufWidth))
Bobty 2:cd2da920cf98 310 return;
Bobty 2:cd2da920cf98 311 // Reset scroll position all rows
Bobty 2:cd2da920cf98 312 for (int i = startRow; i < startRow+numRows; i++)
Bobty 2:cd2da920cf98 313 _hScrollPos[i] = pos;
Bobty 2:cd2da920cf98 314 }
Bobty 2:cd2da920cf98 315
Bobty 2:cd2da920cf98 316 void LEDMatrix::clear(int lineIdx)
Bobty 2:cd2da920cf98 317 {
Bobty 2:cd2da920cf98 318 // Interpret param
Bobty 2:cd2da920cf98 319 int startRow = 0;
Bobty 2:cd2da920cf98 320 int numRows = LED_MATRIX_LEDS_VERTICALLY;
Bobty 2:cd2da920cf98 321 if (!getRowsToWorkOn(lineIdx, startRow, numRows))
Bobty 2:cd2da920cf98 322 return;
Bobty 2:cd2da920cf98 323 // Clear section
Bobty 2:cd2da920cf98 324 uint8_t *ptr = _pDisplayBuf + startRow * (dispBufWidth / 8);
Bobty 2:cd2da920cf98 325 int bytesToZero = numRows * (dispBufWidth / 8);
Bobty 2:cd2da920cf98 326 for (int i = 0; i < bytesToZero; i++)
Bobty 2:cd2da920cf98 327 *ptr++ = 0x00;
Bobty 5:334fc002e200 328 // Stop invert
Bobty 5:334fc002e200 329 for (int i = 0; i < LED_MATRIX_MAX_LINES; i++)
Bobty 5:334fc002e200 330 _lineInvert[i] = false;
Bobty 2:cd2da920cf98 331 }
Bobty 2:cd2da920cf98 332
Bobty 4:40d4afefcd74 333 void LEDMatrix::setScrollRate(int rate)
Bobty 4:40d4afefcd74 334 {
Bobty 4:40d4afefcd74 335 _scrollRate = rate;
Bobty 4:40d4afefcd74 336 }
Bobty 4:40d4afefcd74 337
Bobty 4:40d4afefcd74 338 void LEDMatrix::setFlashRate(int rate)
Bobty 4:40d4afefcd74 339 {
Bobty 4:40d4afefcd74 340 _flashRate = rate;
Bobty 4:40d4afefcd74 341 }
Bobty 4:40d4afefcd74 342
Bobty 2:cd2da920cf98 343 void LEDMatrix::setupScroll(int lineIdx, int scrollWidth, int scrollInc)
Bobty 2:cd2da920cf98 344 {
Bobty 2:cd2da920cf98 345 // Interpret param
Bobty 2:cd2da920cf98 346 int startRow = 0;
Bobty 2:cd2da920cf98 347 int numRows = LED_MATRIX_LEDS_VERTICALLY;
Bobty 2:cd2da920cf98 348 if (!getRowsToWorkOn(lineIdx, startRow, numRows))
Bobty 2:cd2da920cf98 349 return;
Bobty 2:cd2da920cf98 350 scrollWidth = (((scrollWidth / 8) + 1) * 8);
Bobty 2:cd2da920cf98 351 if (scrollWidth <= 0)
Bobty 2:cd2da920cf98 352 return;
Bobty 2:cd2da920cf98 353 for (int i = startRow; i < startRow+numRows; i++)
Bobty 2:cd2da920cf98 354 {
Bobty 2:cd2da920cf98 355 _hScrollPos[i] = 0;
Bobty 2:cd2da920cf98 356 _hScrollWidth[i] = scrollWidth;
Bobty 2:cd2da920cf98 357 }
Bobty 3:1e06e89bc0c9 358 // Store the scroll increment
Bobty 3:1e06e89bc0c9 359 int startLine = 0;
Bobty 3:1e06e89bc0c9 360 int linesToProcess = numLines;
Bobty 3:1e06e89bc0c9 361 if (lineIdx != -1)
Bobty 3:1e06e89bc0c9 362 {
Bobty 3:1e06e89bc0c9 363 if ((lineIdx < 0) || (lineIdx >= numLines))
Bobty 3:1e06e89bc0c9 364 return;
Bobty 3:1e06e89bc0c9 365 startLine = lineIdx;
Bobty 3:1e06e89bc0c9 366 linesToProcess = 1;
Bobty 3:1e06e89bc0c9 367 }
Bobty 3:1e06e89bc0c9 368 for (int i = 0; i < linesToProcess; i++)
Bobty 3:1e06e89bc0c9 369 _lineScrollInc[i+startLine] = scrollInc;
Bobty 2:cd2da920cf98 370 }
Bobty 2:cd2da920cf98 371
Bobty 5:334fc002e200 372 void LEDMatrix::setHighlight(int lineIdx, bool highlightOn)
Bobty 3:1e06e89bc0c9 373 {
Bobty 5:334fc002e200 374 // Store the highlight status
Bobty 3:1e06e89bc0c9 375 int startLine = 0;
Bobty 3:1e06e89bc0c9 376 int linesToProcess = numLines;
Bobty 3:1e06e89bc0c9 377 if (lineIdx != -1)
Bobty 3:1e06e89bc0c9 378 {
Bobty 3:1e06e89bc0c9 379 if ((lineIdx < 0) || (lineIdx >= numLines))
Bobty 3:1e06e89bc0c9 380 return;
Bobty 3:1e06e89bc0c9 381 startLine = lineIdx;
Bobty 3:1e06e89bc0c9 382 linesToProcess = 1;
Bobty 3:1e06e89bc0c9 383 }
Bobty 3:1e06e89bc0c9 384 for (int i = 0; i < linesToProcess; i++)
Bobty 5:334fc002e200 385 _lineHighlight[i+startLine] = highlightOn;
Bobty 3:1e06e89bc0c9 386 }
Bobty 3:1e06e89bc0c9 387
Bobty 2:cd2da920cf98 388 void LEDMatrix::serviceEffects()
Bobty 2:cd2da920cf98 389 {
Bobty 4:40d4afefcd74 390 // Scroll logic
Bobty 4:40d4afefcd74 391 _scrollCounter++;
Bobty 4:40d4afefcd74 392 if (_scrollCounter >= _scrollRate)
Bobty 2:cd2da920cf98 393 {
Bobty 4:40d4afefcd74 394 _scrollCounter = 0;
Bobty 4:40d4afefcd74 395 int rowsInLine = (height / numLines);
Bobty 4:40d4afefcd74 396 for (int i = 0; i < numLines; i++)
Bobty 4:40d4afefcd74 397 {
Bobty 4:40d4afefcd74 398 for (int j = 0; j < rowsInLine; j++)
Bobty 4:40d4afefcd74 399 _hScrollPos[i*rowsInLine+j] += _lineScrollInc[i];
Bobty 4:40d4afefcd74 400 }
Bobty 3:1e06e89bc0c9 401 }
Bobty 3:1e06e89bc0c9 402
Bobty 3:1e06e89bc0c9 403 // Update flash state
Bobty 3:1e06e89bc0c9 404 _flashCounter++;
Bobty 3:1e06e89bc0c9 405 if (_flashCounter >= _flashRate)
Bobty 3:1e06e89bc0c9 406 {
Bobty 3:1e06e89bc0c9 407 _flashCounter = 0;
Bobty 3:1e06e89bc0c9 408 _flashState = !_flashState;
Bobty 4:40d4afefcd74 409 for (int i = 0; i < numLines; i++)
Bobty 5:334fc002e200 410 _lineInvert[i] = _lineHighlight[i] ? _flashState : false;
Bobty 2:cd2da920cf98 411 }
Bobty 2:cd2da920cf98 412 }
Bobty 2:cd2da920cf98 413
Bobty 2:cd2da920cf98 414 // Reverse bits in byte
Bobty 2:cd2da920cf98 415 uint8_t LEDMatrix::reverseBits(uint8_t b)
Bobty 2:cd2da920cf98 416 {
Bobty 2:cd2da920cf98 417 b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
Bobty 2:cd2da920cf98 418 b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
Bobty 2:cd2da920cf98 419 b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
Bobty 2:cd2da920cf98 420 return b;
Bobty 1:79cf2e115449 421 }
Bobty 1:79cf2e115449 422
Bobty 2:cd2da920cf98 423 // Display ASCII char
Bobty 2:cd2da920cf98 424 int LEDMatrix::displayChar(int xPos, int yPos, char ch)
Bobty 1:79cf2e115449 425 {
Bobty 2:cd2da920cf98 426 const int FONT_HEIGHT = 7;
Bobty 2:cd2da920cf98 427 const int FONT_WIDTH = 5;
Bobty 2:cd2da920cf98 428
Bobty 2:cd2da920cf98 429 // Find the width of the character
Bobty 2:cd2da920cf98 430 uint8_t chTotalBits = 0;
Bobty 2:cd2da920cf98 431 int chIdxInFont = (ch % 128) - 0x20;
Bobty 2:cd2da920cf98 432 // Special case for £, euro and yen signs
Bobty 2:cd2da920cf98 433 if ((ch >= 0xa3) && (ch <= 0xa5))
Bobty 2:cd2da920cf98 434 chIdxInFont = ch - 0xa3 + 128 - ' ';
Bobty 2:cd2da920cf98 435 for (int i = 0; i < FONT_HEIGHT; i++)
Bobty 2:cd2da920cf98 436 {
Bobty 2:cd2da920cf98 437 uint8_t chBits = font5x7[chIdxInFont][i];
Bobty 2:cd2da920cf98 438 chTotalBits |= chBits;
Bobty 2:cd2da920cf98 439 }
Bobty 2:cd2da920cf98 440 uint8_t rightShift = 0;
Bobty 2:cd2da920cf98 441 for (int j = 0; j < FONT_WIDTH; j++)
Bobty 2:cd2da920cf98 442 {
Bobty 2:cd2da920cf98 443 if (chTotalBits & 0x01)
Bobty 2:cd2da920cf98 444 break;
Bobty 2:cd2da920cf98 445 chTotalBits = chTotalBits >> 1;
Bobty 2:cd2da920cf98 446 rightShift++;
Bobty 2:cd2da920cf98 447 }
Bobty 2:cd2da920cf98 448 uint8_t charWidth = 8;
Bobty 2:cd2da920cf98 449 for (int j = 0; j < FONT_WIDTH+1; j++)
Bobty 2:cd2da920cf98 450 {
Bobty 2:cd2da920cf98 451 if (chTotalBits & 0x80)
Bobty 2:cd2da920cf98 452 break;
Bobty 2:cd2da920cf98 453 chTotalBits = chTotalBits << 1;
Bobty 2:cd2da920cf98 454 charWidth--;
Bobty 2:cd2da920cf98 455 }
Bobty 2:cd2da920cf98 456
Bobty 2:cd2da920cf98 457 // display character
Bobty 2:cd2da920cf98 458 int xOffset = xPos / 8;
Bobty 2:cd2da920cf98 459 int bitOffset = xPos % 8;
Bobty 2:cd2da920cf98 460 // printf("%c %d %d %d %d\n", ch, charPos, charWidth, xOffset, bitOffset);
Bobty 2:cd2da920cf98 461 if (xOffset >= (dispBufWidth/8))
Bobty 2:cd2da920cf98 462 return 0;
Bobty 2:cd2da920cf98 463
Bobty 2:cd2da920cf98 464 // Copy the bits of the character into the buffer
Bobty 2:cd2da920cf98 465 for (int i = 0; i < FONT_HEIGHT; i++)
Bobty 2:cd2da920cf98 466 {
Bobty 2:cd2da920cf98 467 // Check we don't go off the display buffer
Bobty 2:cd2da920cf98 468 int rowIdx = i + yPos;
Bobty 2:cd2da920cf98 469 if (rowIdx > height)
Bobty 2:cd2da920cf98 470 break;
Bobty 2:cd2da920cf98 471
Bobty 2:cd2da920cf98 472 //
Bobty 2:cd2da920cf98 473 uint8_t chBits = font5x7[chIdxInFont][i] >> rightShift;
Bobty 2:cd2da920cf98 474 int dispBufPos = (rowIdx * (dispBufWidth/8) + xOffset);
Bobty 2:cd2da920cf98 475 _pDisplayBuf[dispBufPos] |= ((chBits << (8 - charWidth)) >> bitOffset);
Bobty 2:cd2da920cf98 476 if (xOffset + 1 < (dispBufWidth/8))
Bobty 2:cd2da920cf98 477 _pDisplayBuf[dispBufPos + 1] |= ((chBits << (8-bitOffset)) << (8 - charWidth));
Bobty 2:cd2da920cf98 478 }
Bobty 2:cd2da920cf98 479
Bobty 2:cd2da920cf98 480 return charWidth;
Bobty 1:79cf2e115449 481 }
Bobty 1:79cf2e115449 482
Bobty 2:cd2da920cf98 483 // Display a large digit
Bobty 2:cd2da920cf98 484 int LEDMatrix::displayLargeDigit(int curX, int curY, char ch)
Bobty 1:79cf2e115449 485 {
Bobty 2:cd2da920cf98 486 // Bounds check
Bobty 2:cd2da920cf98 487 if ((ch < '0') || (ch > '9'))
Bobty 2:cd2da920cf98 488 return 0;
Bobty 2:cd2da920cf98 489
Bobty 2:cd2da920cf98 490 // Get character data
Bobty 2:cd2da920cf98 491 const uint8_t* charData = bigFont[ch-'0'];
Bobty 2:cd2da920cf98 492 int numLines = sizeof(bigFont[0])/sizeof(bigFont[0][0]);
Bobty 2:cd2da920cf98 493
Bobty 2:cd2da920cf98 494 // Find the position and width of the character
Bobty 2:cd2da920cf98 495 uint16_t chTotalBits = 0;
Bobty 2:cd2da920cf98 496 for (int i = 0; i < numLines; i++)
Bobty 2:cd2da920cf98 497 chTotalBits |= charData[i];
Bobty 2:cd2da920cf98 498 uint16_t rightShift = 0;
Bobty 2:cd2da920cf98 499 for (; rightShift < 16; rightShift++)
Bobty 2:cd2da920cf98 500 {
Bobty 2:cd2da920cf98 501 if (chTotalBits & 0x01)
Bobty 2:cd2da920cf98 502 break;
Bobty 2:cd2da920cf98 503 chTotalBits = chTotalBits >> 1;
Bobty 2:cd2da920cf98 504 }
Bobty 2:cd2da920cf98 505 uint16_t charWidth = 16;
Bobty 2:cd2da920cf98 506 for (; charWidth > 0; charWidth--)
Bobty 2:cd2da920cf98 507 {
Bobty 2:cd2da920cf98 508 if (chTotalBits & 0x8000)
Bobty 2:cd2da920cf98 509 break;
Bobty 2:cd2da920cf98 510 chTotalBits = chTotalBits << 1;
Bobty 2:cd2da920cf98 511 }
Bobty 2:cd2da920cf98 512
Bobty 2:cd2da920cf98 513 // display character
Bobty 2:cd2da920cf98 514 int xOffset = curX / 8;
Bobty 2:cd2da920cf98 515 int bitOffset = curX % 8;
Bobty 2:cd2da920cf98 516 // printf("%c %d %d %d %d %d\n", ch, curX, charWidth, rightShift, xOffset, bitOffset);
Bobty 2:cd2da920cf98 517 if (xOffset >= (dispBufWidth/8))
Bobty 2:cd2da920cf98 518 return 0;
Bobty 2:cd2da920cf98 519 for (int i = 0; i < numLines; i++)
Bobty 2:cd2da920cf98 520 {
Bobty 2:cd2da920cf98 521 uint32_t chBits = charData[i] >> rightShift;
Bobty 2:cd2da920cf98 522 chBits = (chBits << (24-charWidth)) >> bitOffset;
Bobty 2:cd2da920cf98 523 for (int j = 0; j < 3; j++)
Bobty 2:cd2da920cf98 524 {
Bobty 2:cd2da920cf98 525 if (xOffset + j >= (dispBufWidth/8))
Bobty 2:cd2da920cf98 526 break;
Bobty 2:cd2da920cf98 527 _pDisplayBuf[(i + curY) * (dispBufWidth/8) + xOffset + j] |= ((chBits >> (16-j*8)) & 0xff);
Bobty 2:cd2da920cf98 528 }
Bobty 2:cd2da920cf98 529 }
Bobty 2:cd2da920cf98 530
Bobty 2:cd2da920cf98 531 return charWidth;
Bobty 1:79cf2e115449 532 }
Bobty 2:cd2da920cf98 533
Bobty 2:cd2da920cf98 534 // Display line of characters
Bobty 2:cd2da920cf98 535 int LEDMatrix::displayLine(int lineIdx, const char* line)
Bobty 2:cd2da920cf98 536 {
Bobty 2:cd2da920cf98 537 if (lineIdx >= numLines)
Bobty 2:cd2da920cf98 538 lineIdx = 0;
Bobty 2:cd2da920cf98 539 _isBusy = true;
Bobty 2:cd2da920cf98 540 int curX = 0;
Bobty 2:cd2da920cf98 541 int curY = lineIdx * height/numLines;
Bobty 2:cd2da920cf98 542 for (int chIdx = 0; chIdx < strlen(line); chIdx++)
Bobty 2:cd2da920cf98 543 {
Bobty 2:cd2da920cf98 544 curX += displayChar(curX, curY, line[chIdx]) + _charSeparation;
Bobty 2:cd2da920cf98 545 }
Bobty 2:cd2da920cf98 546 _isBusy = false;
Bobty 2:cd2da920cf98 547 return curX;
Bobty 2:cd2da920cf98 548 }
Bobty 2:cd2da920cf98 549