Adafruit Led Matrix 64x32 Lib

Dependents:   Adafruit-64x32-PWM-Demo

Revision:
1:99abd7449a45
Parent:
0:cdc5e3a73147
Child:
2:e37a437cf602
diff -r cdc5e3a73147 -r 99abd7449a45 LedMatrix.cpp
--- a/LedMatrix.cpp	Wed Oct 11 00:36:17 2017 +0000
+++ b/LedMatrix.cpp	Tue Oct 24 02:59:55 2017 +0000
@@ -1,19 +1,43 @@
 #include "LedMatrix.h"
+#include "FastIO.h"
+#include "rtos.h"
+
+#if (defined(TARGET_STM32F303K8))
 
 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)
+FastOut<D3> LAT;    //  Data latch    - active low (pulse up after data load)
+FastOut<D4> OE;     //  Output enable - active low (hold high during data load, bring low after LAT pulse)
+
+FastOut<D9> CLK;    //  Data clock    - rising edge
+FastOut<D10> R1;     //  RED   Serial in for upper half
+FastOut<D11> G1;      //  GREEN Serial in for upper half
+FastOut<D12> B1;      //  BLUE  Serial in for upper half
+FastOut<D13> R2;     //  RED   Serial in for lower half
+FastOut<A0> G2;      //  GREEN Serial in for lower half
+FastOut<A1> B2;      //  BLUE  Serial in for lower half
+
+#elif (defined(TARGET_STM32F767ZI))
 
-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
+BusOut ABCD(A0,A1,A2,A3); // Row address.
+FastOut<PD_2> OE;     //  Output enable - active low (hold high during data load, bring low after LAT pulse)
+FastOut<PG_2> LAT;    //  Data latch    - active low (pulse up after data load)
+FastOut<PG_3> CLK;    //  Data clock    - rising edge
+
+FastOut<PD_7> R1;     //  RED   Serial in for upper half
+FastOut<PD_6> G1;      //  GREEN Serial in for upper half
+FastOut<PD_5> B1;      //  BLUE  Serial in for upper half
+FastOut<PD_4> R2;     //  RED   Serial in for lower half
+FastOut<PD_3> G2;      //  GREEN Serial in for lower half
+FastOut<A4> B2;      //  BLUE  Serial in for lower half
+
+#endif
 
 LedMatrix::LedMatrix() : Adafruit_GFX(WIDTH, HEIGHT)
 {
+    tickCount = 0;
+    shownBuffer = 0;
+    drawBuffer = 0;
+    refreshed = false;
 }
 
 // Promote 3/3/3 RGB to Adafruit_GFX 5/6/5
@@ -97,9 +121,27 @@
 }
 
 
-void LedMatrix::drawPixel(int16_t x, int16_t y, uint16_t color)
+void LedMatrix::drawPixel(int16_t x, int16_t y, uint16_t c)
 {
-    Pset(x, y, color);
+    int r, g, b;
+    
+    r =  (c >> 10) & 0x1F;        // RRRRRgggggbbbbb
+    g = (c >>  5) & 0x1F; // rrrrrGGGGGbbbbb
+    b = c & 0x1F; // rrrrrgggggBBBBB
+     
+    for(int p=0;p<PLANES;p++)
+    {
+        if (y >= HEIGHT_DEV_2)
+        {
+            // Keep last 3 bits (B2G2R2b1g1r1)
+            gm[drawBuffer][p][y - HEIGHT_DEV_2][x] = (gm[drawBuffer][p][y - HEIGHT_DEV_2][x] & 0b111000) + ((r >> p) & 1) + (((g >> p) & 1) << 1) + (((b >> p) & 1) << 2);
+        }
+        else
+        {
+            // keep first 3 bits (b2g2r2B1G1R1)
+            gm[drawBuffer][p][y][x] = (gm[drawBuffer][p][y][x] & 0b000111) + ((((r >> p) & 1) + (((g << 1) >> p) & 2) + (((b << 2) >> p) & 4)) << 3);
+        }            
+    }
 }
 
 void LedMatrix::Init()
@@ -110,69 +152,122 @@
     OE = HIGH; //display off
     ABCD = 0;
     plane=0;
+    currRow=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
+    char *val = (char *) &gm[shownBuffer][plane][Row][WIDTH-1];
+    
     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];
+        int value = *val;
+        
+        R1 = (value & 1); // Red bit, upper half
+        G1 = (value & 2); // Green bit, upper half
+        B1 = (value & 4); // Blue bit, upper half
         
-        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
+        R2 = (value & 8); // Red bit, lower half
+        G2 = (value & 16); // Green bit, lower half
+        B2 = (value & 32); // Blue bit, lower half
         CLK = HIGH;                 // tick (clock bit in)
+        for(int h=0;h<5;h++);
         CLK = LOW;                  // tock
+        for(int h=0;h<5;h++);
+        val--;
     }
     LAT = HIGH; // Latch entire row
+    for(int h=0;h<5;h++);
     LAT = LOW;
 }
 
-void LedMatrix::Pset(int16_t x, int16_t y, uint16_t c)
+void LedMatrix::CopyBuffer(char oldBuffer, char newBuffer)
 {
-    int r, g, b;
+    char *oldBuff = (char *) &gm[oldBuffer][0][0][0];
+    char *newBuff = (char *) &gm[newBuffer][0][0][0];
     
-    r =  c >> 12;        // RRRRrggggggbbbbb
-    g = (c >>  7) & 0xF; // rrrrrGGGGggbbbbb
-    b = (c >>  1) & 0xF; // rrrrrggggggBBBBb
-    
-    for(int p=0;p<PLANES;p++)
+    for(uint32_t buf = 0;buf<(PLANES * HEIGHT_DEV_2 * WIDTH);buf++)
     {
-        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);
-        }            
+        *newBuff = *oldBuff;
+        newBuff++;
+        oldBuff++;
+    }
+}
+
+void LedMatrix::SetDoubleBuffer(bool setDoubleBuffer)
+{
+    if (setDoubleBuffer)
+    {
+        shownBuffer = 1;
+        drawBuffer = 0;   
+    }
+    else
+    {
+        shownBuffer = 0;
+        drawBuffer = 0;
     }
 }
 
-void LedMatrix::Paint()
+void LedMatrix::Swap(bool copyBuffer)
 {
-    if (plane >= (PLANES - 1))
+    if (shownBuffer == 0)
     {
-        plane = 0;
+        shownBuffer = 1;
+        drawBuffer = 0;
     }
     else
     {
-        plane++;
+        drawBuffer = 1;
+        shownBuffer = 0;
+    }
+    
+    if (copyBuffer)
+    {
+        CopyBuffer(shownBuffer, drawBuffer);
     }
-        
-    // Write graphics memory to display
-    for(int Row=0; Row<HEIGHT_DEV_2; Row++) {
+}
+
+// Break painting up into 8 rows to keep CPU int time down
+void LedMatrix::Paint()
+{      
+    if ((plane >= 1 && tickCount >= (1 << (plane - 1)) && currRow == 0 && !refreshed)
+        || (refreshed && tickCount >= (1 << (PLANES - 1))))
+    {
         OE = HIGH; // Disable output
-        WrRow(Row);
+        if (refreshed)
+        {
+            tickCount = 0;
+            refreshed = false;
+        }
+    }
+    
+    // Write graphics memory to display
+    if (tickCount >= (1 << plane) && !refreshed)
+    {
+        tickCount = 0;
+        OE = HIGH; // Disable output
+        WrRow(currRow);
         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.
+        currRow++;
+    
+        if (currRow >= HEIGHT_DEV_2)
+        {
+            currRow = 0;
+            
+            if (plane >= (PLANES - 1))
+            {
+                plane = 0;
+                refreshed = true;
+            }
+            else
+            {
+                plane++;
+            }
+        }
     }
-    OE = HIGH; // Disable output
+    else
+    {
+        tickCount++;
+    }
 }
\ No newline at end of file