Adafruit Led Matrix 64x32 Lib
Dependents: Adafruit-64x32-PWM-Demo
Diff: LedMatrix.cpp
- Revision:
- 0:cdc5e3a73147
- Child:
- 1:99abd7449a45
diff -r 000000000000 -r cdc5e3a73147 LedMatrix.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LedMatrix.cpp Wed Oct 11 00:36:17 2017 +0000 @@ -0,0 +1,178 @@ +#include "LedMatrix.h" + +BusOut ABCD(D5,D6,D7,D8); // Row address. +DigitalOut LAT(D3); // Data latch - active low (pulse up after data load) +DigitalOut OE(D4); // Output enable - active low (hold high during data load, bring low after LAT pulse) + +DigitalOut CLK(D9); // Data clock - rising edge +DigitalOut R1(D10); // RED Serial in for upper half +DigitalOut G1(D11); // GREEN Serial in for upper half +DigitalOut B1(D12); // BLUE Serial in for upper half +DigitalOut R2(D13); // RED Serial in for lower half +DigitalOut G2(A0); // GREEN Serial in for lower half +DigitalOut B2(A1); // BLUE Serial in for lower half + +LedMatrix::LedMatrix() : Adafruit_GFX(WIDTH, HEIGHT) +{ +} + +// Promote 3/3/3 RGB to Adafruit_GFX 5/6/5 +uint16_t LedMatrix::Color333(uint8_t r, uint8_t g, uint8_t b) { + // RRRrrGGGgggBBBbb + return ((r & 0x7) << 13) | ((r & 0x6) << 10) | + ((g & 0x7) << 8) | ((g & 0x7) << 5) | + ((b & 0x7) << 2) | ((b & 0x6) >> 1); +} + +// Promote 4/4/4 RGB to Adafruit_GFX 5/6/5 +uint16_t LedMatrix::Color444(uint8_t r, uint8_t g, uint8_t b) { + // RRRRrGGGGggBBBBb + return ((r & 0xF) << 12) | ((r & 0x8) << 8) | + ((g & 0xF) << 7) | ((g & 0xC) << 3) | + ((b & 0xF) << 1) | ((b & 0x8) >> 3); +} + +// Demote 8/8/8 to Adafruit_GFX 5/6/5 +// If no gamma flag passed, assume linear color +uint16_t LedMatrix::Color888(uint8_t r, uint8_t g, uint8_t b) { + return ((uint16_t)(r & 0xF8) << 8) | ((uint16_t)(g & 0xFC) << 3) | (b >> 3); +} + +// 8/8/8 -> gamma -> 5/6/5 +uint16_t LedMatrix::Color888( + uint8_t r, uint8_t g, uint8_t b, bool gflag) { + if(gflag) { // Gamma-corrected color? + r = gamma[r]; // Gamma correction table maps + g = gamma[g]; // 8-bit input to 4-bit output + b = gamma[b]; + return ((uint16_t)r << 12) | ((uint16_t)(r & 0x8) << 8) | // 4/4/4->5/6/5 + ((uint16_t)g << 7) | ((uint16_t)(g & 0xC) << 3) | + ( b << 1) | ( b >> 3); + } // else linear (uncorrected) color + return ((uint16_t)(r & 0xF8) << 8) | ((uint16_t)(g & 0xFC) << 3) | (b >> 3); +} + +uint16_t LedMatrix::ColorHSV( + long hue, uint8_t sat, uint8_t val, bool gflag) { + + uint8_t r, g, b, lo; + uint16_t s1, v1; + + // Hue + hue %= 1536; // -1535 to +1535 + if(hue < 0) hue += 1536; // 0 to +1535 + lo = hue & 255; // Low byte = primary/secondary color mix + switch(hue >> 8) { // High byte = sextant of colorwheel + case 0 : r = 255 ; g = lo ; b = 0 ; break; // R to Y + case 1 : r = 255 - lo; g = 255 ; b = 0 ; break; // Y to G + case 2 : r = 0 ; g = 255 ; b = lo ; break; // G to C + case 3 : r = 0 ; g = 255 - lo; b = 255 ; break; // C to B + case 4 : r = lo ; g = 0 ; b = 255 ; break; // B to M + default: r = 255 ; g = 0 ; b = 255 - lo; break; // M to R + } + + // Saturation: add 1 so range is 1 to 256, allowig a quick shift operation + // on the result rather than a costly divide, while the type upgrade to int + // avoids repeated type conversions in both directions. + s1 = sat + 1; + r = 255 - (((255 - r) * s1) >> 8); + g = 255 - (((255 - g) * s1) >> 8); + b = 255 - (((255 - b) * s1) >> 8); + + // Value (brightness) & 16-bit color reduction: similar to above, add 1 + // to allow shifts, and upgrade to int makes other conversions implicit. + v1 = val + 1; + if(gflag) { // Gamma-corrected color? + r = gamma[(r * v1) >> 8]; // Gamma correction table maps + g = gamma[(g * v1) >> 8]; // 8-bit input to 4-bit output + b = gamma[(b * v1) >> 8]; + } else { // linear (uncorrected) color + r = (r * v1) >> 12; // 4-bit results + g = (g * v1) >> 12; + b = (b * v1) >> 12; + } + return (r << 12) | ((r & 0x8) << 8) | // 4/4/4 -> 5/6/5 + (g << 7) | ((g & 0xC) << 3) | + (b << 1) | ( b >> 3); +} + + +void LedMatrix::drawPixel(int16_t x, int16_t y, uint16_t color) +{ + Pset(x, y, color); +} + +void LedMatrix::Init() +{ + // Set up things to a known state + CLK = LOW; + LAT = LOW; + OE = HIGH; //display off + ABCD = 0; + plane=0; +} + +void LedMatrix::WrRow(unsigned char Row) +{ + // Write specified row (and row+8) to display. Valid input: 0 to 7. + ABCD=(HEIGHT_DEV_2-1)-Row; // Set row address + 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. + char val = gm[col][Row][plane]; + + R1 = (val & 1); // Red bit, upper half + G1 = (val & 2); // Green bit, upper half + B1 = (val & 4); // Blue bit, upper half + + R2 = (val & 8); // Red bit, lower half + G2 = (val & 16); // Green bit, lower half + B2 = (val & 32); // Blue bit, lower half + CLK = HIGH; // tick (clock bit in) + CLK = LOW; // tock + } + LAT = HIGH; // Latch entire row + LAT = LOW; +} + +void LedMatrix::Pset(int16_t x, int16_t y, uint16_t c) +{ + int r, g, b; + + r = c >> 12; // RRRRrggggggbbbbb + g = (c >> 7) & 0xF; // rrrrrGGGGggbbbbb + b = (c >> 1) & 0xF; // rrrrrggggggBBBBb + + for(int p=0;p<PLANES;p++) + { + if (y >= HEIGHT_DEV_2) + { + // Keep last 3 bits + 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); + } + else + { + // keep first 3 bits + gm[x][y][p] = (gm[x][y][p] & 0b000111) + ((((r >> p) & 1) + (((g << 1) >> p) & 2) + (((b << 2) >> p) & 4)) << 3); + } + } +} + +void LedMatrix::Paint() +{ + if (plane >= (PLANES - 1)) + { + plane = 0; + } + else + { + plane++; + } + + // Write graphics memory to display + for(int Row=0; Row<HEIGHT_DEV_2; Row++) { + OE = HIGH; // Disable output + WrRow(Row); + OE = LOW; // Enable output + wait_us(2 * (1 << plane)); // Wasting some time. Use for whatever else. Probably better with a ticker for the display refresh. + } + OE = HIGH; // Disable output +} \ No newline at end of file