Adafruit Led Matrix 64x32 Lib

Dependents:   Adafruit-64x32-PWM-Demo

Committer:
davidr99
Date:
Wed Oct 11 00:36:17 2017 +0000
Revision:
0:cdc5e3a73147
Child:
1:99abd7449a45
Changed over to use Adafruit GFX

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davidr99 0:cdc5e3a73147 1 #include "LedMatrix.h"
davidr99 0:cdc5e3a73147 2
davidr99 0:cdc5e3a73147 3 BusOut ABCD(D5,D6,D7,D8); // Row address.
davidr99 0:cdc5e3a73147 4 DigitalOut LAT(D3); // Data latch - active low (pulse up after data load)
davidr99 0:cdc5e3a73147 5 DigitalOut OE(D4); // Output enable - active low (hold high during data load, bring low after LAT pulse)
davidr99 0:cdc5e3a73147 6
davidr99 0:cdc5e3a73147 7 DigitalOut CLK(D9); // Data clock - rising edge
davidr99 0:cdc5e3a73147 8 DigitalOut R1(D10); // RED Serial in for upper half
davidr99 0:cdc5e3a73147 9 DigitalOut G1(D11); // GREEN Serial in for upper half
davidr99 0:cdc5e3a73147 10 DigitalOut B1(D12); // BLUE Serial in for upper half
davidr99 0:cdc5e3a73147 11 DigitalOut R2(D13); // RED Serial in for lower half
davidr99 0:cdc5e3a73147 12 DigitalOut G2(A0); // GREEN Serial in for lower half
davidr99 0:cdc5e3a73147 13 DigitalOut B2(A1); // BLUE Serial in for lower half
davidr99 0:cdc5e3a73147 14
davidr99 0:cdc5e3a73147 15 LedMatrix::LedMatrix() : Adafruit_GFX(WIDTH, HEIGHT)
davidr99 0:cdc5e3a73147 16 {
davidr99 0:cdc5e3a73147 17 }
davidr99 0:cdc5e3a73147 18
davidr99 0:cdc5e3a73147 19 // Promote 3/3/3 RGB to Adafruit_GFX 5/6/5
davidr99 0:cdc5e3a73147 20 uint16_t LedMatrix::Color333(uint8_t r, uint8_t g, uint8_t b) {
davidr99 0:cdc5e3a73147 21 // RRRrrGGGgggBBBbb
davidr99 0:cdc5e3a73147 22 return ((r & 0x7) << 13) | ((r & 0x6) << 10) |
davidr99 0:cdc5e3a73147 23 ((g & 0x7) << 8) | ((g & 0x7) << 5) |
davidr99 0:cdc5e3a73147 24 ((b & 0x7) << 2) | ((b & 0x6) >> 1);
davidr99 0:cdc5e3a73147 25 }
davidr99 0:cdc5e3a73147 26
davidr99 0:cdc5e3a73147 27 // Promote 4/4/4 RGB to Adafruit_GFX 5/6/5
davidr99 0:cdc5e3a73147 28 uint16_t LedMatrix::Color444(uint8_t r, uint8_t g, uint8_t b) {
davidr99 0:cdc5e3a73147 29 // RRRRrGGGGggBBBBb
davidr99 0:cdc5e3a73147 30 return ((r & 0xF) << 12) | ((r & 0x8) << 8) |
davidr99 0:cdc5e3a73147 31 ((g & 0xF) << 7) | ((g & 0xC) << 3) |
davidr99 0:cdc5e3a73147 32 ((b & 0xF) << 1) | ((b & 0x8) >> 3);
davidr99 0:cdc5e3a73147 33 }
davidr99 0:cdc5e3a73147 34
davidr99 0:cdc5e3a73147 35 // Demote 8/8/8 to Adafruit_GFX 5/6/5
davidr99 0:cdc5e3a73147 36 // If no gamma flag passed, assume linear color
davidr99 0:cdc5e3a73147 37 uint16_t LedMatrix::Color888(uint8_t r, uint8_t g, uint8_t b) {
davidr99 0:cdc5e3a73147 38 return ((uint16_t)(r & 0xF8) << 8) | ((uint16_t)(g & 0xFC) << 3) | (b >> 3);
davidr99 0:cdc5e3a73147 39 }
davidr99 0:cdc5e3a73147 40
davidr99 0:cdc5e3a73147 41 // 8/8/8 -> gamma -> 5/6/5
davidr99 0:cdc5e3a73147 42 uint16_t LedMatrix::Color888(
davidr99 0:cdc5e3a73147 43 uint8_t r, uint8_t g, uint8_t b, bool gflag) {
davidr99 0:cdc5e3a73147 44 if(gflag) { // Gamma-corrected color?
davidr99 0:cdc5e3a73147 45 r = gamma[r]; // Gamma correction table maps
davidr99 0:cdc5e3a73147 46 g = gamma[g]; // 8-bit input to 4-bit output
davidr99 0:cdc5e3a73147 47 b = gamma[b];
davidr99 0:cdc5e3a73147 48 return ((uint16_t)r << 12) | ((uint16_t)(r & 0x8) << 8) | // 4/4/4->5/6/5
davidr99 0:cdc5e3a73147 49 ((uint16_t)g << 7) | ((uint16_t)(g & 0xC) << 3) |
davidr99 0:cdc5e3a73147 50 ( b << 1) | ( b >> 3);
davidr99 0:cdc5e3a73147 51 } // else linear (uncorrected) color
davidr99 0:cdc5e3a73147 52 return ((uint16_t)(r & 0xF8) << 8) | ((uint16_t)(g & 0xFC) << 3) | (b >> 3);
davidr99 0:cdc5e3a73147 53 }
davidr99 0:cdc5e3a73147 54
davidr99 0:cdc5e3a73147 55 uint16_t LedMatrix::ColorHSV(
davidr99 0:cdc5e3a73147 56 long hue, uint8_t sat, uint8_t val, bool gflag) {
davidr99 0:cdc5e3a73147 57
davidr99 0:cdc5e3a73147 58 uint8_t r, g, b, lo;
davidr99 0:cdc5e3a73147 59 uint16_t s1, v1;
davidr99 0:cdc5e3a73147 60
davidr99 0:cdc5e3a73147 61 // Hue
davidr99 0:cdc5e3a73147 62 hue %= 1536; // -1535 to +1535
davidr99 0:cdc5e3a73147 63 if(hue < 0) hue += 1536; // 0 to +1535
davidr99 0:cdc5e3a73147 64 lo = hue & 255; // Low byte = primary/secondary color mix
davidr99 0:cdc5e3a73147 65 switch(hue >> 8) { // High byte = sextant of colorwheel
davidr99 0:cdc5e3a73147 66 case 0 : r = 255 ; g = lo ; b = 0 ; break; // R to Y
davidr99 0:cdc5e3a73147 67 case 1 : r = 255 - lo; g = 255 ; b = 0 ; break; // Y to G
davidr99 0:cdc5e3a73147 68 case 2 : r = 0 ; g = 255 ; b = lo ; break; // G to C
davidr99 0:cdc5e3a73147 69 case 3 : r = 0 ; g = 255 - lo; b = 255 ; break; // C to B
davidr99 0:cdc5e3a73147 70 case 4 : r = lo ; g = 0 ; b = 255 ; break; // B to M
davidr99 0:cdc5e3a73147 71 default: r = 255 ; g = 0 ; b = 255 - lo; break; // M to R
davidr99 0:cdc5e3a73147 72 }
davidr99 0:cdc5e3a73147 73
davidr99 0:cdc5e3a73147 74 // Saturation: add 1 so range is 1 to 256, allowig a quick shift operation
davidr99 0:cdc5e3a73147 75 // on the result rather than a costly divide, while the type upgrade to int
davidr99 0:cdc5e3a73147 76 // avoids repeated type conversions in both directions.
davidr99 0:cdc5e3a73147 77 s1 = sat + 1;
davidr99 0:cdc5e3a73147 78 r = 255 - (((255 - r) * s1) >> 8);
davidr99 0:cdc5e3a73147 79 g = 255 - (((255 - g) * s1) >> 8);
davidr99 0:cdc5e3a73147 80 b = 255 - (((255 - b) * s1) >> 8);
davidr99 0:cdc5e3a73147 81
davidr99 0:cdc5e3a73147 82 // Value (brightness) & 16-bit color reduction: similar to above, add 1
davidr99 0:cdc5e3a73147 83 // to allow shifts, and upgrade to int makes other conversions implicit.
davidr99 0:cdc5e3a73147 84 v1 = val + 1;
davidr99 0:cdc5e3a73147 85 if(gflag) { // Gamma-corrected color?
davidr99 0:cdc5e3a73147 86 r = gamma[(r * v1) >> 8]; // Gamma correction table maps
davidr99 0:cdc5e3a73147 87 g = gamma[(g * v1) >> 8]; // 8-bit input to 4-bit output
davidr99 0:cdc5e3a73147 88 b = gamma[(b * v1) >> 8];
davidr99 0:cdc5e3a73147 89 } else { // linear (uncorrected) color
davidr99 0:cdc5e3a73147 90 r = (r * v1) >> 12; // 4-bit results
davidr99 0:cdc5e3a73147 91 g = (g * v1) >> 12;
davidr99 0:cdc5e3a73147 92 b = (b * v1) >> 12;
davidr99 0:cdc5e3a73147 93 }
davidr99 0:cdc5e3a73147 94 return (r << 12) | ((r & 0x8) << 8) | // 4/4/4 -> 5/6/5
davidr99 0:cdc5e3a73147 95 (g << 7) | ((g & 0xC) << 3) |
davidr99 0:cdc5e3a73147 96 (b << 1) | ( b >> 3);
davidr99 0:cdc5e3a73147 97 }
davidr99 0:cdc5e3a73147 98
davidr99 0:cdc5e3a73147 99
davidr99 0:cdc5e3a73147 100 void LedMatrix::drawPixel(int16_t x, int16_t y, uint16_t color)
davidr99 0:cdc5e3a73147 101 {
davidr99 0:cdc5e3a73147 102 Pset(x, y, color);
davidr99 0:cdc5e3a73147 103 }
davidr99 0:cdc5e3a73147 104
davidr99 0:cdc5e3a73147 105 void LedMatrix::Init()
davidr99 0:cdc5e3a73147 106 {
davidr99 0:cdc5e3a73147 107 // Set up things to a known state
davidr99 0:cdc5e3a73147 108 CLK = LOW;
davidr99 0:cdc5e3a73147 109 LAT = LOW;
davidr99 0:cdc5e3a73147 110 OE = HIGH; //display off
davidr99 0:cdc5e3a73147 111 ABCD = 0;
davidr99 0:cdc5e3a73147 112 plane=0;
davidr99 0:cdc5e3a73147 113 }
davidr99 0:cdc5e3a73147 114
davidr99 0:cdc5e3a73147 115 void LedMatrix::WrRow(unsigned char Row)
davidr99 0:cdc5e3a73147 116 {
davidr99 0:cdc5e3a73147 117 // Write specified row (and row+8) to display. Valid input: 0 to 7.
davidr99 0:cdc5e3a73147 118 ABCD=(HEIGHT_DEV_2-1)-Row; // Set row address
davidr99 0:cdc5e3a73147 119 for(int col=(WIDTH-1); col >= 0; col--) { // To daisychain more displays, I guess you would have to increase this counter to n*32 columns. Might mirror though.
davidr99 0:cdc5e3a73147 120 char val = gm[col][Row][plane];
davidr99 0:cdc5e3a73147 121
davidr99 0:cdc5e3a73147 122 R1 = (val & 1); // Red bit, upper half
davidr99 0:cdc5e3a73147 123 G1 = (val & 2); // Green bit, upper half
davidr99 0:cdc5e3a73147 124 B1 = (val & 4); // Blue bit, upper half
davidr99 0:cdc5e3a73147 125
davidr99 0:cdc5e3a73147 126 R2 = (val & 8); // Red bit, lower half
davidr99 0:cdc5e3a73147 127 G2 = (val & 16); // Green bit, lower half
davidr99 0:cdc5e3a73147 128 B2 = (val & 32); // Blue bit, lower half
davidr99 0:cdc5e3a73147 129 CLK = HIGH; // tick (clock bit in)
davidr99 0:cdc5e3a73147 130 CLK = LOW; // tock
davidr99 0:cdc5e3a73147 131 }
davidr99 0:cdc5e3a73147 132 LAT = HIGH; // Latch entire row
davidr99 0:cdc5e3a73147 133 LAT = LOW;
davidr99 0:cdc5e3a73147 134 }
davidr99 0:cdc5e3a73147 135
davidr99 0:cdc5e3a73147 136 void LedMatrix::Pset(int16_t x, int16_t y, uint16_t c)
davidr99 0:cdc5e3a73147 137 {
davidr99 0:cdc5e3a73147 138 int r, g, b;
davidr99 0:cdc5e3a73147 139
davidr99 0:cdc5e3a73147 140 r = c >> 12; // RRRRrggggggbbbbb
davidr99 0:cdc5e3a73147 141 g = (c >> 7) & 0xF; // rrrrrGGGGggbbbbb
davidr99 0:cdc5e3a73147 142 b = (c >> 1) & 0xF; // rrrrrggggggBBBBb
davidr99 0:cdc5e3a73147 143
davidr99 0:cdc5e3a73147 144 for(int p=0;p<PLANES;p++)
davidr99 0:cdc5e3a73147 145 {
davidr99 0:cdc5e3a73147 146 if (y >= HEIGHT_DEV_2)
davidr99 0:cdc5e3a73147 147 {
davidr99 0:cdc5e3a73147 148 // Keep last 3 bits
davidr99 0:cdc5e3a73147 149 gm[x][y - HEIGHT_DEV_2][p] = (gm[x][y - HEIGHT_DEV_2][p] & 0b111000) + ((r >> p) & 1) + (((g << 1) >> p) & 2) + (((b << 2) >> p) & 4);
davidr99 0:cdc5e3a73147 150 }
davidr99 0:cdc5e3a73147 151 else
davidr99 0:cdc5e3a73147 152 {
davidr99 0:cdc5e3a73147 153 // keep first 3 bits
davidr99 0:cdc5e3a73147 154 gm[x][y][p] = (gm[x][y][p] & 0b000111) + ((((r >> p) & 1) + (((g << 1) >> p) & 2) + (((b << 2) >> p) & 4)) << 3);
davidr99 0:cdc5e3a73147 155 }
davidr99 0:cdc5e3a73147 156 }
davidr99 0:cdc5e3a73147 157 }
davidr99 0:cdc5e3a73147 158
davidr99 0:cdc5e3a73147 159 void LedMatrix::Paint()
davidr99 0:cdc5e3a73147 160 {
davidr99 0:cdc5e3a73147 161 if (plane >= (PLANES - 1))
davidr99 0:cdc5e3a73147 162 {
davidr99 0:cdc5e3a73147 163 plane = 0;
davidr99 0:cdc5e3a73147 164 }
davidr99 0:cdc5e3a73147 165 else
davidr99 0:cdc5e3a73147 166 {
davidr99 0:cdc5e3a73147 167 plane++;
davidr99 0:cdc5e3a73147 168 }
davidr99 0:cdc5e3a73147 169
davidr99 0:cdc5e3a73147 170 // Write graphics memory to display
davidr99 0:cdc5e3a73147 171 for(int Row=0; Row<HEIGHT_DEV_2; Row++) {
davidr99 0:cdc5e3a73147 172 OE = HIGH; // Disable output
davidr99 0:cdc5e3a73147 173 WrRow(Row);
davidr99 0:cdc5e3a73147 174 OE = LOW; // Enable output
davidr99 0:cdc5e3a73147 175 wait_us(2 * (1 << plane)); // Wasting some time. Use for whatever else. Probably better with a ticker for the display refresh.
davidr99 0:cdc5e3a73147 176 }
davidr99 0:cdc5e3a73147 177 OE = HIGH; // Disable output
davidr99 0:cdc5e3a73147 178 }