LED matrix library for http://goo.gl/y6VnO6
LEDMatrix.cpp@0:13728deac7a7, 2013-11-08 (annotated)
- Committer:
- yihui
- Date:
- Fri Nov 08 06:45:52 2013 +0000
- Revision:
- 0:13728deac7a7
- Child:
- 1:b528f8e32726
initial
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 | 0:13728deac7a7 | 63 | uint8_t *byte = displaybuf + x * 8 + y / 8; |
yihui | 0:13728deac7a7 | 64 | uint8_t bit = y % 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 | 0:13728deac7a7 | 82 | void LEDMatrix::drawImage(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t *image) |
yihui | 0:13728deac7a7 | 83 | { |
yihui | 0:13728deac7a7 | 84 | ASSERT(0 == ((x2 - x1) % 8)); |
yihui | 0:13728deac7a7 | 85 | |
yihui | 0:13728deac7a7 | 86 | for (uint16_t x = x1; x < x2; x++) { |
yihui | 0:13728deac7a7 | 87 | for (uint16_t y = y1; y < y2; y++) { |
yihui | 0:13728deac7a7 | 88 | uint8_t *byte = image + x * 8 + y / 8; |
yihui | 0:13728deac7a7 | 89 | uint8_t bit = 7 - (y % 8); |
yihui | 0:13728deac7a7 | 90 | uint8_t pixel = (*byte >> bit) & 1; |
yihui | 0:13728deac7a7 | 91 | |
yihui | 0:13728deac7a7 | 92 | drawPoint(x, y, pixel); |
yihui | 0:13728deac7a7 | 93 | } |
yihui | 0:13728deac7a7 | 94 | } |
yihui | 0:13728deac7a7 | 95 | } |
yihui | 0:13728deac7a7 | 96 | |
yihui | 0:13728deac7a7 | 97 | void LEDMatrix::clear() |
yihui | 0:13728deac7a7 | 98 | { |
yihui | 0:13728deac7a7 | 99 | uint8_t *ptr = displaybuf; |
yihui | 0:13728deac7a7 | 100 | for (uint16_t i = 0; i < (width * height / 8); i++) { |
yihui | 0:13728deac7a7 | 101 | *ptr = 0x00; |
yihui | 0:13728deac7a7 | 102 | ptr++; |
yihui | 0:13728deac7a7 | 103 | } |
yihui | 0:13728deac7a7 | 104 | } |
yihui | 0:13728deac7a7 | 105 | |
yihui | 0:13728deac7a7 | 106 | void LEDMatrix::reverse() |
yihui | 0:13728deac7a7 | 107 | { |
yihui | 0:13728deac7a7 | 108 | mask = ~mask; |
yihui | 0:13728deac7a7 | 109 | } |
yihui | 0:13728deac7a7 | 110 | |
yihui | 0:13728deac7a7 | 111 | uint8_t LEDMatrix::isReversed() |
yihui | 0:13728deac7a7 | 112 | { |
yihui | 0:13728deac7a7 | 113 | return mask; |
yihui | 0:13728deac7a7 | 114 | } |
yihui | 0:13728deac7a7 | 115 | |
yihui | 0:13728deac7a7 | 116 | void LEDMatrix::scan() |
yihui | 0:13728deac7a7 | 117 | { |
yihui | 0:13728deac7a7 | 118 | static uint8_t row = 0; |
yihui | 0:13728deac7a7 | 119 | |
yihui | 0:13728deac7a7 | 120 | if (!state) { |
yihui | 0:13728deac7a7 | 121 | return; |
yihui | 0:13728deac7a7 | 122 | } |
yihui | 0:13728deac7a7 | 123 | |
yihui | 0:13728deac7a7 | 124 | uint8_t *head = displaybuf + row * (width / 8); |
yihui | 0:13728deac7a7 | 125 | for (uint8_t line = 0; line < (height / 16); line++) { |
yihui | 0:13728deac7a7 | 126 | uint8_t *ptr = head; |
yihui | 0:13728deac7a7 | 127 | head += line * width * 2; |
yihui | 0:13728deac7a7 | 128 | |
yihui | 0:13728deac7a7 | 129 | for (uint8_t byte = 0; byte < (width / 8); byte++) { |
yihui | 0:13728deac7a7 | 130 | uint8_t pixels = *ptr; |
yihui | 0:13728deac7a7 | 131 | ptr++; |
yihui | 0:13728deac7a7 | 132 | pixels = pixels ^ mask; // reverse: mask = 0xff, normal: mask =0x00 |
yihui | 0:13728deac7a7 | 133 | for (uint8_t bit = 0; bit < 8; bit++) { |
yihui | 0:13728deac7a7 | 134 | clk = 0; |
yihui | 0:13728deac7a7 | 135 | r1 = pixels & (0x80 >> bit); |
yihui | 0:13728deac7a7 | 136 | clk = 1; |
yihui | 0:13728deac7a7 | 137 | } |
yihui | 0:13728deac7a7 | 138 | } |
yihui | 0:13728deac7a7 | 139 | } |
yihui | 0:13728deac7a7 | 140 | |
yihui | 0:13728deac7a7 | 141 | oe = 1; // disable display |
yihui | 0:13728deac7a7 | 142 | |
yihui | 0:13728deac7a7 | 143 | // select row |
yihui | 0:13728deac7a7 | 144 | a = (row & 0x01); |
yihui | 0:13728deac7a7 | 145 | b = (row & 0x02); |
yihui | 0:13728deac7a7 | 146 | c = (row & 0x04); |
yihui | 0:13728deac7a7 | 147 | d = (row & 0x08); |
yihui | 0:13728deac7a7 | 148 | |
yihui | 0:13728deac7a7 | 149 | // latch data |
yihui | 0:13728deac7a7 | 150 | stb = 0; |
yihui | 0:13728deac7a7 | 151 | stb = 1; |
yihui | 0:13728deac7a7 | 152 | |
yihui | 0:13728deac7a7 | 153 | oe = 0; // enable display |
yihui | 0:13728deac7a7 | 154 | |
yihui | 0:13728deac7a7 | 155 | row = (row + 1) & 0x0F; |
yihui | 0:13728deac7a7 | 156 | } |
yihui | 0:13728deac7a7 | 157 | |
yihui | 0:13728deac7a7 | 158 | void LEDMatrix::on() |
yihui | 0:13728deac7a7 | 159 | { |
yihui | 0:13728deac7a7 | 160 | state = 1; |
yihui | 0:13728deac7a7 | 161 | } |
yihui | 0:13728deac7a7 | 162 | |
yihui | 0:13728deac7a7 | 163 | void LEDMatrix::off() |
yihui | 0:13728deac7a7 | 164 | { |
yihui | 0:13728deac7a7 | 165 | state = 0; |
yihui | 0:13728deac7a7 | 166 | oe = 1; |
yihui | 0:13728deac7a7 | 167 | } |
yihui | 0:13728deac7a7 | 168 |