LED matrix library for http://goo.gl/y6VnO6
LEDMatrix.cpp@1:b528f8e32726, 2014-02-18 (annotated)
- Committer:
- Yihui Xiong
- Date:
- Tue Feb 18 10:51:13 2014 +0800
- Revision:
- 1:b528f8e32726
- Parent:
- 0:13728deac7a7
bug fix
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; |
yihui | 0:13728deac7a7 | 44 | } |
yihui | 0:13728deac7a7 | 45 | |
yihui | 0:13728deac7a7 | 46 | void LEDMatrix::begin(uint8_t *displaybuf, uint16_t width, uint16_t height) |
yihui | 0:13728deac7a7 | 47 | { |
yihui | 0:13728deac7a7 | 48 | ASSERT(0 == (width % 32)); |
yihui | 0:13728deac7a7 | 49 | ASSERT(0 == (height % 16)); |
yihui | 0:13728deac7a7 | 50 | |
yihui | 0:13728deac7a7 | 51 | this->displaybuf = displaybuf; |
yihui | 0:13728deac7a7 | 52 | this->width = width; |
yihui | 0:13728deac7a7 | 53 | this->height = height; |
yihui | 0:13728deac7a7 | 54 | |
yihui | 0:13728deac7a7 | 55 | state = 1; |
yihui | 0:13728deac7a7 | 56 | } |
yihui | 0:13728deac7a7 | 57 | |
yihui | 0:13728deac7a7 | 58 | void LEDMatrix::drawPoint(uint16_t x, uint16_t y, uint8_t pixel) |
yihui | 0:13728deac7a7 | 59 | { |
yihui | 0:13728deac7a7 | 60 | ASSERT(width > x); |
yihui | 0:13728deac7a7 | 61 | ASSERT(height > y); |
yihui | 0:13728deac7a7 | 62 | |
Yihui Xiong |
1:b528f8e32726 | 63 | uint8_t *byte = displaybuf + x / 8 + y * width / 8; |
Yihui Xiong |
1:b528f8e32726 | 64 | uint8_t bit = x % 8; |
yihui | 0:13728deac7a7 | 65 | |
yihui | 0:13728deac7a7 | 66 | if (pixel) { |
yihui | 0:13728deac7a7 | 67 | *byte |= 0x80 >> bit; |
yihui | 0:13728deac7a7 | 68 | } else { |
yihui | 0:13728deac7a7 | 69 | *byte &= ~(0x80 >> bit); |
yihui | 0:13728deac7a7 | 70 | } |
yihui | 0:13728deac7a7 | 71 | } |
yihui | 0:13728deac7a7 | 72 | |
yihui | 0:13728deac7a7 | 73 | void LEDMatrix::drawRect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t pixel) |
yihui | 0:13728deac7a7 | 74 | { |
yihui | 0:13728deac7a7 | 75 | for (uint16_t x = x1; x < x2; x++) { |
yihui | 0:13728deac7a7 | 76 | for (uint16_t y = y1; y < y2; y++) { |
yihui | 0:13728deac7a7 | 77 | drawPoint(x, y, pixel); |
yihui | 0:13728deac7a7 | 78 | } |
yihui | 0:13728deac7a7 | 79 | } |
yihui | 0:13728deac7a7 | 80 | } |
yihui | 0:13728deac7a7 | 81 | |
Yihui Xiong |
1:b528f8e32726 | 82 | void LEDMatrix::drawImage(uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height, const uint8_t *image) |
yihui | 0:13728deac7a7 | 83 | { |
Yihui Xiong |
1:b528f8e32726 | 84 | for (uint16_t y = 0; y < height; y++) { |
Yihui Xiong |
1:b528f8e32726 | 85 | for (uint16_t x = 0; x < width; x++) { |
Yihui Xiong |
1:b528f8e32726 | 86 | const uint8_t *byte = image + (x + y * width) / 8; |
Yihui Xiong |
1:b528f8e32726 | 87 | uint8_t bit = 7 - x % 8; |
yihui | 0:13728deac7a7 | 88 | uint8_t pixel = (*byte >> bit) & 1; |
yihui | 0:13728deac7a7 | 89 | |
Yihui Xiong |
1:b528f8e32726 | 90 | drawPoint(x + xoffset, y + yoffset, pixel); |
yihui | 0:13728deac7a7 | 91 | } |
yihui | 0:13728deac7a7 | 92 | } |
yihui | 0:13728deac7a7 | 93 | } |
yihui | 0:13728deac7a7 | 94 | |
yihui | 0:13728deac7a7 | 95 | void LEDMatrix::clear() |
yihui | 0:13728deac7a7 | 96 | { |
yihui | 0:13728deac7a7 | 97 | uint8_t *ptr = displaybuf; |
yihui | 0:13728deac7a7 | 98 | for (uint16_t i = 0; i < (width * height / 8); i++) { |
yihui | 0:13728deac7a7 | 99 | *ptr = 0x00; |
yihui | 0:13728deac7a7 | 100 | ptr++; |
yihui | 0:13728deac7a7 | 101 | } |
yihui | 0:13728deac7a7 | 102 | } |
yihui | 0:13728deac7a7 | 103 | |
yihui | 0:13728deac7a7 | 104 | void LEDMatrix::reverse() |
yihui | 0:13728deac7a7 | 105 | { |
yihui | 0:13728deac7a7 | 106 | mask = ~mask; |
yihui | 0:13728deac7a7 | 107 | } |
yihui | 0:13728deac7a7 | 108 | |
yihui | 0:13728deac7a7 | 109 | uint8_t LEDMatrix::isReversed() |
yihui | 0:13728deac7a7 | 110 | { |
yihui | 0:13728deac7a7 | 111 | return mask; |
yihui | 0:13728deac7a7 | 112 | } |
yihui | 0:13728deac7a7 | 113 | |
yihui | 0:13728deac7a7 | 114 | void LEDMatrix::scan() |
yihui | 0:13728deac7a7 | 115 | { |
yihui | 0:13728deac7a7 | 116 | static uint8_t row = 0; |
yihui | 0:13728deac7a7 | 117 | |
yihui | 0:13728deac7a7 | 118 | if (!state) { |
yihui | 0:13728deac7a7 | 119 | return; |
yihui | 0:13728deac7a7 | 120 | } |
yihui | 0:13728deac7a7 | 121 | |
yihui | 0:13728deac7a7 | 122 | uint8_t *head = displaybuf + row * (width / 8); |
yihui | 0:13728deac7a7 | 123 | for (uint8_t line = 0; line < (height / 16); line++) { |
yihui | 0:13728deac7a7 | 124 | uint8_t *ptr = head; |
Yihui Xiong |
1:b528f8e32726 | 125 | head += width * 2; // width * 16 / 8 |
yihui | 0:13728deac7a7 | 126 | |
yihui | 0:13728deac7a7 | 127 | for (uint8_t byte = 0; byte < (width / 8); byte++) { |
yihui | 0:13728deac7a7 | 128 | uint8_t pixels = *ptr; |
yihui | 0:13728deac7a7 | 129 | ptr++; |
yihui | 0:13728deac7a7 | 130 | pixels = pixels ^ mask; // reverse: mask = 0xff, normal: mask =0x00 |
yihui | 0:13728deac7a7 | 131 | for (uint8_t bit = 0; bit < 8; bit++) { |
yihui | 0:13728deac7a7 | 132 | clk = 0; |
yihui | 0:13728deac7a7 | 133 | r1 = pixels & (0x80 >> bit); |
yihui | 0:13728deac7a7 | 134 | clk = 1; |
yihui | 0:13728deac7a7 | 135 | } |
yihui | 0:13728deac7a7 | 136 | } |
yihui | 0:13728deac7a7 | 137 | } |
yihui | 0:13728deac7a7 | 138 | |
yihui | 0:13728deac7a7 | 139 | oe = 1; // disable display |
yihui | 0:13728deac7a7 | 140 | |
yihui | 0:13728deac7a7 | 141 | // select row |
yihui | 0:13728deac7a7 | 142 | a = (row & 0x01); |
yihui | 0:13728deac7a7 | 143 | b = (row & 0x02); |
yihui | 0:13728deac7a7 | 144 | c = (row & 0x04); |
yihui | 0:13728deac7a7 | 145 | d = (row & 0x08); |
yihui | 0:13728deac7a7 | 146 | |
yihui | 0:13728deac7a7 | 147 | // latch data |
yihui | 0:13728deac7a7 | 148 | stb = 0; |
yihui | 0:13728deac7a7 | 149 | stb = 1; |
yihui | 0:13728deac7a7 | 150 | |
yihui | 0:13728deac7a7 | 151 | oe = 0; // enable display |
yihui | 0:13728deac7a7 | 152 | |
yihui | 0:13728deac7a7 | 153 | row = (row + 1) & 0x0F; |
yihui | 0:13728deac7a7 | 154 | } |
yihui | 0:13728deac7a7 | 155 | |
yihui | 0:13728deac7a7 | 156 | void LEDMatrix::on() |
yihui | 0:13728deac7a7 | 157 | { |
yihui | 0:13728deac7a7 | 158 | state = 1; |
yihui | 0:13728deac7a7 | 159 | } |
yihui | 0:13728deac7a7 | 160 | |
yihui | 0:13728deac7a7 | 161 | void LEDMatrix::off() |
yihui | 0:13728deac7a7 | 162 | { |
yihui | 0:13728deac7a7 | 163 | state = 0; |
yihui | 0:13728deac7a7 | 164 | oe = 1; |
yihui | 0:13728deac7a7 | 165 | } |
yihui | 0:13728deac7a7 | 166 |