Forked LEDMatrix and added horizontal scrolling
Fork of LEDMatrix by
LEDMatrix.cpp@1:79cf2e115449, 2016-01-11 (annotated)
- Committer:
- Bobty
- Date:
- Mon Jan 11 21:05:53 2016 +0000
- Revision:
- 1:79cf2e115449
- Parent:
- 0:13728deac7a7
- Child:
- 2:cd2da920cf98
Implemented horizontal scrolling
Who changed what in which revision?
User | Revision | Line number | New 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 |
yihui | 0:13728deac7a7 | 19 | */ |
yihui | 0:13728deac7a7 | 20 | |
yihui | 0:13728deac7a7 | 21 | #include "LEDMatrix.h" |
yihui | 0:13728deac7a7 | 22 | #include "mbed.h" |
yihui | 0:13728deac7a7 | 23 | |
yihui | 0:13728deac7a7 | 24 | #if 0 |
yihui | 0:13728deac7a7 | 25 | #define ASSERT(e) if (!(e)) { Serial.println(#e); while (1); } |
yihui | 0:13728deac7a7 | 26 | #else |
yihui | 0:13728deac7a7 | 27 | #define ASSERT(e) |
yihui | 0:13728deac7a7 | 28 | #endif |
yihui | 0:13728deac7a7 | 29 | |
yihui | 0:13728deac7a7 | 30 | LEDMatrix::LEDMatrix(PinName pinA, PinName pinB, PinName pinC, PinName pinD, PinName pinOE, PinName pinR1, PinName pinSTB, PinName pinCLK) : |
yihui | 0:13728deac7a7 | 31 | a(pinA), b(pinB), c(pinC), d(pinD), oe(pinOE), r1(pinR1), stb(pinSTB), clk(pinCLK) |
yihui | 0:13728deac7a7 | 32 | { |
yihui | 0:13728deac7a7 | 33 | this->clk = clk; |
yihui | 0:13728deac7a7 | 34 | this->r1 = r1; |
yihui | 0:13728deac7a7 | 35 | this->stb = stb; |
yihui | 0:13728deac7a7 | 36 | this->oe = oe; |
yihui | 0:13728deac7a7 | 37 | this->a = a; |
yihui | 0:13728deac7a7 | 38 | this->b = b; |
yihui | 0:13728deac7a7 | 39 | this->c = c; |
yihui | 0:13728deac7a7 | 40 | this->d = d; |
yihui | 0:13728deac7a7 | 41 | |
yihui | 0:13728deac7a7 | 42 | mask = 0xff; |
yihui | 0:13728deac7a7 | 43 | state = 0; |
Bobty | 1:79cf2e115449 | 44 | _horizontalScrollPos = 0; |
yihui | 0:13728deac7a7 | 45 | } |
yihui | 0:13728deac7a7 | 46 | |
yihui | 0:13728deac7a7 | 47 | void LEDMatrix::begin(uint8_t *displaybuf, uint16_t width, uint16_t height) |
yihui | 0:13728deac7a7 | 48 | { |
yihui | 0:13728deac7a7 | 49 | ASSERT(0 == (width % 32)); |
yihui | 0:13728deac7a7 | 50 | ASSERT(0 == (height % 16)); |
yihui | 0:13728deac7a7 | 51 | |
yihui | 0:13728deac7a7 | 52 | this->displaybuf = displaybuf; |
yihui | 0:13728deac7a7 | 53 | this->width = width; |
yihui | 0:13728deac7a7 | 54 | this->height = height; |
yihui | 0:13728deac7a7 | 55 | |
yihui | 0:13728deac7a7 | 56 | state = 1; |
yihui | 0:13728deac7a7 | 57 | } |
yihui | 0:13728deac7a7 | 58 | |
yihui | 0:13728deac7a7 | 59 | void LEDMatrix::drawPoint(uint16_t x, uint16_t y, uint8_t pixel) |
yihui | 0:13728deac7a7 | 60 | { |
yihui | 0:13728deac7a7 | 61 | ASSERT(width > x); |
yihui | 0:13728deac7a7 | 62 | ASSERT(height > y); |
yihui | 0:13728deac7a7 | 63 | |
Bobty | 1:79cf2e115449 | 64 | uint8_t *byte = displaybuf + (height - 1 - y) * width / 8 + (width - 1 - x) / 8; |
Bobty | 1:79cf2e115449 | 65 | uint8_t bit = (width - 1 - x) % 8; |
yihui | 0:13728deac7a7 | 66 | |
yihui | 0:13728deac7a7 | 67 | if (pixel) { |
yihui | 0:13728deac7a7 | 68 | *byte |= 0x80 >> bit; |
yihui | 0:13728deac7a7 | 69 | } else { |
yihui | 0:13728deac7a7 | 70 | *byte &= ~(0x80 >> bit); |
yihui | 0:13728deac7a7 | 71 | } |
yihui | 0:13728deac7a7 | 72 | } |
yihui | 0:13728deac7a7 | 73 | |
yihui | 0:13728deac7a7 | 74 | void LEDMatrix::drawRect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t pixel) |
yihui | 0:13728deac7a7 | 75 | { |
yihui | 0:13728deac7a7 | 76 | for (uint16_t x = x1; x < x2; x++) { |
yihui | 0:13728deac7a7 | 77 | for (uint16_t y = y1; y < y2; y++) { |
yihui | 0:13728deac7a7 | 78 | drawPoint(x, y, pixel); |
yihui | 0:13728deac7a7 | 79 | } |
yihui | 0:13728deac7a7 | 80 | } |
yihui | 0:13728deac7a7 | 81 | } |
yihui | 0:13728deac7a7 | 82 | |
yihui | 0:13728deac7a7 | 83 | void LEDMatrix::drawImage(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t *image) |
yihui | 0:13728deac7a7 | 84 | { |
yihui | 0:13728deac7a7 | 85 | ASSERT(0 == ((x2 - x1) % 8)); |
yihui | 0:13728deac7a7 | 86 | |
yihui | 0:13728deac7a7 | 87 | for (uint16_t x = x1; x < x2; x++) { |
yihui | 0:13728deac7a7 | 88 | for (uint16_t y = y1; y < y2; y++) { |
yihui | 0:13728deac7a7 | 89 | uint8_t *byte = image + x * 8 + y / 8; |
yihui | 0:13728deac7a7 | 90 | uint8_t bit = 7 - (y % 8); |
yihui | 0:13728deac7a7 | 91 | uint8_t pixel = (*byte >> bit) & 1; |
yihui | 0:13728deac7a7 | 92 | |
yihui | 0:13728deac7a7 | 93 | drawPoint(x, y, pixel); |
yihui | 0:13728deac7a7 | 94 | } |
yihui | 0:13728deac7a7 | 95 | } |
yihui | 0:13728deac7a7 | 96 | } |
yihui | 0:13728deac7a7 | 97 | |
yihui | 0:13728deac7a7 | 98 | void LEDMatrix::clear() |
yihui | 0:13728deac7a7 | 99 | { |
yihui | 0:13728deac7a7 | 100 | uint8_t *ptr = displaybuf; |
yihui | 0:13728deac7a7 | 101 | for (uint16_t i = 0; i < (width * height / 8); i++) { |
yihui | 0:13728deac7a7 | 102 | *ptr = 0x00; |
yihui | 0:13728deac7a7 | 103 | ptr++; |
yihui | 0:13728deac7a7 | 104 | } |
yihui | 0:13728deac7a7 | 105 | } |
yihui | 0:13728deac7a7 | 106 | |
yihui | 0:13728deac7a7 | 107 | void LEDMatrix::reverse() |
yihui | 0:13728deac7a7 | 108 | { |
yihui | 0:13728deac7a7 | 109 | mask = ~mask; |
yihui | 0:13728deac7a7 | 110 | } |
yihui | 0:13728deac7a7 | 111 | |
yihui | 0:13728deac7a7 | 112 | uint8_t LEDMatrix::isReversed() |
yihui | 0:13728deac7a7 | 113 | { |
yihui | 0:13728deac7a7 | 114 | return mask; |
yihui | 0:13728deac7a7 | 115 | } |
yihui | 0:13728deac7a7 | 116 | |
yihui | 0:13728deac7a7 | 117 | void LEDMatrix::scan() |
yihui | 0:13728deac7a7 | 118 | { |
yihui | 0:13728deac7a7 | 119 | static uint8_t row = 0; |
yihui | 0:13728deac7a7 | 120 | |
Bobty | 1:79cf2e115449 | 121 | if (!state) |
Bobty | 1:79cf2e115449 | 122 | { |
yihui | 0:13728deac7a7 | 123 | return; |
yihui | 0:13728deac7a7 | 124 | } |
yihui | 0:13728deac7a7 | 125 | |
yihui | 0:13728deac7a7 | 126 | uint8_t *head = displaybuf + row * (width / 8); |
Bobty | 1:79cf2e115449 | 127 | for (uint8_t line = 0; line < (height / 16); line++) |
Bobty | 1:79cf2e115449 | 128 | { |
yihui | 0:13728deac7a7 | 129 | uint8_t *ptr = head; |
yihui | 0:13728deac7a7 | 130 | head += line * width * 2; |
yihui | 0:13728deac7a7 | 131 | |
Bobty | 1:79cf2e115449 | 132 | for (uint8_t byteIdx = 0; byteIdx < (width / 8); byteIdx++) |
Bobty | 1:79cf2e115449 | 133 | { |
Bobty | 1:79cf2e115449 | 134 | uint8_t* pByte1 = ptr + (((byteIdx*8 + width - _horizontalScrollPos + 7) % width) / 8); |
Bobty | 1:79cf2e115449 | 135 | uint8_t* pByte2 = ptr + (((byteIdx*8 + width - _horizontalScrollPos - 1) % width) / 8); |
Bobty | 1:79cf2e115449 | 136 | int bitOffset = _horizontalScrollPos % 8; |
Bobty | 1:79cf2e115449 | 137 | uint8_t pixels = ((*pByte1) >> bitOffset) + (((*pByte2) << (8 - bitOffset)) % 256); |
Bobty | 1:79cf2e115449 | 138 | |
Bobty | 1:79cf2e115449 | 139 | // uint8_t pixels = *ptr; |
Bobty | 1:79cf2e115449 | 140 | // ptr++; |
yihui | 0:13728deac7a7 | 141 | pixels = pixels ^ mask; // reverse: mask = 0xff, normal: mask =0x00 |
Bobty | 1:79cf2e115449 | 142 | for (uint8_t bit = 0; bit < 8; bit++) |
Bobty | 1:79cf2e115449 | 143 | { |
yihui | 0:13728deac7a7 | 144 | clk = 0; |
yihui | 0:13728deac7a7 | 145 | r1 = pixels & (0x80 >> bit); |
Bobty | 1:79cf2e115449 | 146 | // wait_us(1); |
yihui | 0:13728deac7a7 | 147 | clk = 1; |
yihui | 0:13728deac7a7 | 148 | } |
yihui | 0:13728deac7a7 | 149 | } |
yihui | 0:13728deac7a7 | 150 | } |
yihui | 0:13728deac7a7 | 151 | |
yihui | 0:13728deac7a7 | 152 | oe = 1; // disable display |
yihui | 0:13728deac7a7 | 153 | |
yihui | 0:13728deac7a7 | 154 | // select row |
yihui | 0:13728deac7a7 | 155 | a = (row & 0x01); |
yihui | 0:13728deac7a7 | 156 | b = (row & 0x02); |
yihui | 0:13728deac7a7 | 157 | c = (row & 0x04); |
yihui | 0:13728deac7a7 | 158 | d = (row & 0x08); |
yihui | 0:13728deac7a7 | 159 | |
yihui | 0:13728deac7a7 | 160 | // latch data |
yihui | 0:13728deac7a7 | 161 | stb = 0; |
Bobty | 1:79cf2e115449 | 162 | // wait_us(1); |
yihui | 0:13728deac7a7 | 163 | stb = 1; |
yihui | 0:13728deac7a7 | 164 | |
yihui | 0:13728deac7a7 | 165 | oe = 0; // enable display |
yihui | 0:13728deac7a7 | 166 | |
yihui | 0:13728deac7a7 | 167 | row = (row + 1) & 0x0F; |
yihui | 0:13728deac7a7 | 168 | } |
yihui | 0:13728deac7a7 | 169 | |
yihui | 0:13728deac7a7 | 170 | void LEDMatrix::on() |
yihui | 0:13728deac7a7 | 171 | { |
yihui | 0:13728deac7a7 | 172 | state = 1; |
yihui | 0:13728deac7a7 | 173 | } |
yihui | 0:13728deac7a7 | 174 | |
yihui | 0:13728deac7a7 | 175 | void LEDMatrix::off() |
yihui | 0:13728deac7a7 | 176 | { |
yihui | 0:13728deac7a7 | 177 | state = 0; |
yihui | 0:13728deac7a7 | 178 | oe = 1; |
yihui | 0:13728deac7a7 | 179 | } |
yihui | 0:13728deac7a7 | 180 | |
Bobty | 1:79cf2e115449 | 181 | void LEDMatrix::scrollReset() |
Bobty | 1:79cf2e115449 | 182 | { |
Bobty | 1:79cf2e115449 | 183 | _horizontalScrollPos = 0; |
Bobty | 1:79cf2e115449 | 184 | } |
Bobty | 1:79cf2e115449 | 185 | |
Bobty | 1:79cf2e115449 | 186 | void LEDMatrix::scrollLeft() |
Bobty | 1:79cf2e115449 | 187 | { |
Bobty | 1:79cf2e115449 | 188 | _horizontalScrollPos++; |
Bobty | 1:79cf2e115449 | 189 | if (_horizontalScrollPos >= width) |
Bobty | 1:79cf2e115449 | 190 | _horizontalScrollPos = 0; |
Bobty | 1:79cf2e115449 | 191 | } |
Bobty | 1:79cf2e115449 | 192 | |
Bobty | 1:79cf2e115449 | 193 | void LEDMatrix::scrollToPos(int pos) |
Bobty | 1:79cf2e115449 | 194 | { |
Bobty | 1:79cf2e115449 | 195 | if ((pos <= 0) || (pos >= width)) |
Bobty | 1:79cf2e115449 | 196 | return; |
Bobty | 1:79cf2e115449 | 197 | _horizontalScrollPos = pos; |
Bobty | 1:79cf2e115449 | 198 | } |