Adafruit Led Matrix 64x32 Lib
Dependents: Adafruit-64x32-PWM-Demo
LedMatrix.cpp
- Committer:
- davidr99
- Date:
- 2017-10-11
- Revision:
- 0:cdc5e3a73147
- Child:
- 1:99abd7449a45
File content as of revision 0:cdc5e3a73147:
#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 }