Adafruit Led Matrix 64x32 Lib

Dependents:   Adafruit-64x32-PWM-Demo

Revision:
0:cdc5e3a73147
Child:
1:99abd7449a45
--- /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