A demo for Adafruit 64x32 demo with PWM

Dependencies:   mbed-rtos BufferedSerial Adafruit_GFX_MBED LedMatrix-PWM FastIO mbed-dev

main.cpp

Committer:
davidr99
Date:
2017-10-08
Revision:
0:9f43f6e0d6ad
Child:
1:442e873e4f52

File content as of revision 0:9f43f6e0d6ad:

/*
The goal of this program is to show the basic connections and workings of Adafruits 32x16 RGB LED matrix board (http://www.adafruit.com/products/420),
also sold on other places, for instance http://www.ebay.com/itm/PH6-RGB-Full-Color-LED-16-32-Dot-Matrix-Display-Module-/310303408628?pt=LH_DefaultDomain_0&hash=item483f8641f4 (no
affiliation with either of them).
This program is not intended to be highly optimized or a guideline in C programming in any way (more of the opposite actually).
To have more than 7 colors on this thing, you need to implement software PWM of some sort. I have obviously not done that, but if YOU do, please let me know!
Adafruit have a wicked demo program for an arduino - www.youtube.com/watch?v=lY-flFEfsHo
There are probably lots of ways to make this perform better, perhaps by using Neal Hormans port of the Adafruit_GFX library (http://mbed.org/users/nkhorman/code/Adafruit_GFX/).
No error checking or out-of-bounds checking is done. Use at your own peril.
For more detailed information on the driver chip, see http://www.bjtopspace.com/ziliao/CYT62726.pdf
Although the chips on my board says jx15020, I've been informed that they are equvivalent to the CYT62726, and so far it's a match.
Feel free to use all or parts of this work.
If you choose to do so, I would appreciate a small mentioning in the scrolling opening credits ;)

Best regards,
Hugo Harming
upgraded@hotmail.com
*/

#include "mbed.h"
#include "rtos.h"
#define LOW 0
#define HIGH 1

BusOut ABCD(D5,D6,D7,D8); // Row address.
DigitalOut CLK(D9);    //  Data clock    - rising edge
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 R1(D10);     //  RED   Serial in for upper half
DigitalOut R2(D13);     //  RED   Serial in for lower half
DigitalOut G1(D11);      //  GREEN Serial in for upper half
DigitalOut G2(A0);      //  GREEN Serial in for lower half
DigitalOut B1(D12);      //  BLUE  Serial in for upper half
DigitalOut B2(A1);      //  BLUE  Serial in for lower half

const int nPlanes = 5;

unsigned char gm[64][16][nPlanes]; // Buffer with 32x6 bytes. Graphics memory if you like.
unsigned int plane; //        Counter for demo code

void Init()
{
    // Set up things to a known state
    CLK = LOW;
    LAT = LOW;
    OE = HIGH; //display off
    ABCD = 0;
    plane=0;
}

void WrRow(unsigned char Row)
{
    // Write specified row (and row+8) to display. Valid input: 0 to 7.
    ABCD=15-Row; // Set row address
    for(int col=63; 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 Pset(unsigned char x,unsigned char y, unsigned long c)
{
    int r, g, b;
    
    r = (c & 0xFF);            // Extract red bit from color
    g = (c & 0xFF00) >> 8;         // Extract green bit from color
    b = (c & 0xFF0000) >> 16;       // Extract blue bit from color
    
    for(int p=0;p<nPlanes;p++)
    {
        if (y >= 16)
        {
            // Keep last 3 bits
            gm[x][y - 16][p] = (gm[x][y - 16][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 Paint()
{
    if (plane >= (nPlanes - 1))
    {
        plane = 0;
    }
    else
    {
        plane++;
    }
        
    // Write graphics memory to display
    for(int Row=0; Row<16; 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
}

void PaintThread()
{
    Paint();
}

int main()
{
    Init(); // Set things up    
    Ticker ticker;
    ticker.attach(PaintThread, 0.003);
    
    while(1) {
    
        for(int x=0;x<64;x++)
        {
            for(int y=0;y<32;y++)
            {
                Pset(x, y, 0xFF0101);
            }   
            //Paint(); // Display refresh time sets loop duration.
        }
        
        Thread::wait(1000);
    
        for(int c=0; c<16; c++) {
            for(int x=c; x<(63-c); x++) {// Top side
                Pset(x,c,c);
                Thread::wait(10);
                //Paint(); // Display refresh time sets loop duration.
            }
            for(int y=c; y<(31-c); y++) {// Right side
                Pset(63-c,y,c << 8);
                Thread::wait(10);
                //Paint();
            }
            for(int x=(63-c); x>=c; x--) {// Bottom side
                Pset(x,(31-c),c << 16);
                Thread::wait(10);
                //Paint();
            }
            for(int y=(31-c); y>=c; y--) { // Left side
                Pset(c,y,c << 8);
                Thread::wait(10);
                //Paint();
            }
        }
        
        Thread::wait(1000);
        
        /*
        for(long w=0;w<1000;w++)
        {
            Paint(); // Display refresh time sets loop duration.
        }*/
    }
}