A demo for Adafruit 64x32 demo with PWM
Dependencies: mbed-rtos BufferedSerial Adafruit_GFX_MBED LedMatrix-PWM FastIO mbed-dev
main.cpp@1:442e873e4f52, 2017-10-08 (annotated)
- Committer:
- davidr99
- Date:
- Sun Oct 08 02:32:21 2017 +0000
- Revision:
- 1:442e873e4f52
- Parent:
- 0:9f43f6e0d6ad
- Child:
- 2:6bfb86f8c9d3
Inital checkin of LED Matrix PWM 64x32
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
davidr99 | 0:9f43f6e0d6ad | 1 | /* |
davidr99 | 1:442e873e4f52 | 2 | Based on http://os.mbed.com/users/RRacer/code/Adafruit-16x32-basic-demo/ |
davidr99 | 0:9f43f6e0d6ad | 3 | |
davidr99 | 0:9f43f6e0d6ad | 4 | */ |
davidr99 | 0:9f43f6e0d6ad | 5 | |
davidr99 | 0:9f43f6e0d6ad | 6 | #include "mbed.h" |
davidr99 | 0:9f43f6e0d6ad | 7 | #include "rtos.h" |
davidr99 | 0:9f43f6e0d6ad | 8 | #define LOW 0 |
davidr99 | 0:9f43f6e0d6ad | 9 | #define HIGH 1 |
davidr99 | 0:9f43f6e0d6ad | 10 | |
davidr99 | 0:9f43f6e0d6ad | 11 | BusOut ABCD(D5,D6,D7,D8); // Row address. |
davidr99 | 0:9f43f6e0d6ad | 12 | DigitalOut CLK(D9); // Data clock - rising edge |
davidr99 | 0:9f43f6e0d6ad | 13 | DigitalOut LAT(D3); // Data latch - active low (pulse up after data load) |
davidr99 | 0:9f43f6e0d6ad | 14 | DigitalOut OE(D4); // Output enable - active low (hold high during data load, bring low after LAT pulse) |
davidr99 | 0:9f43f6e0d6ad | 15 | DigitalOut R1(D10); // RED Serial in for upper half |
davidr99 | 0:9f43f6e0d6ad | 16 | DigitalOut R2(D13); // RED Serial in for lower half |
davidr99 | 0:9f43f6e0d6ad | 17 | DigitalOut G1(D11); // GREEN Serial in for upper half |
davidr99 | 0:9f43f6e0d6ad | 18 | DigitalOut G2(A0); // GREEN Serial in for lower half |
davidr99 | 0:9f43f6e0d6ad | 19 | DigitalOut B1(D12); // BLUE Serial in for upper half |
davidr99 | 0:9f43f6e0d6ad | 20 | DigitalOut B2(A1); // BLUE Serial in for lower half |
davidr99 | 0:9f43f6e0d6ad | 21 | |
davidr99 | 0:9f43f6e0d6ad | 22 | const int nPlanes = 5; |
davidr99 | 0:9f43f6e0d6ad | 23 | |
davidr99 | 0:9f43f6e0d6ad | 24 | unsigned char gm[64][16][nPlanes]; // Buffer with 32x6 bytes. Graphics memory if you like. |
davidr99 | 0:9f43f6e0d6ad | 25 | unsigned int plane; // Counter for demo code |
davidr99 | 0:9f43f6e0d6ad | 26 | |
davidr99 | 0:9f43f6e0d6ad | 27 | void Init() |
davidr99 | 0:9f43f6e0d6ad | 28 | { |
davidr99 | 0:9f43f6e0d6ad | 29 | // Set up things to a known state |
davidr99 | 0:9f43f6e0d6ad | 30 | CLK = LOW; |
davidr99 | 0:9f43f6e0d6ad | 31 | LAT = LOW; |
davidr99 | 0:9f43f6e0d6ad | 32 | OE = HIGH; //display off |
davidr99 | 0:9f43f6e0d6ad | 33 | ABCD = 0; |
davidr99 | 0:9f43f6e0d6ad | 34 | plane=0; |
davidr99 | 0:9f43f6e0d6ad | 35 | } |
davidr99 | 0:9f43f6e0d6ad | 36 | |
davidr99 | 0:9f43f6e0d6ad | 37 | void WrRow(unsigned char Row) |
davidr99 | 0:9f43f6e0d6ad | 38 | { |
davidr99 | 0:9f43f6e0d6ad | 39 | // Write specified row (and row+8) to display. Valid input: 0 to 7. |
davidr99 | 0:9f43f6e0d6ad | 40 | ABCD=15-Row; // Set row address |
davidr99 | 0:9f43f6e0d6ad | 41 | 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. |
davidr99 | 0:9f43f6e0d6ad | 42 | char val = gm[col][Row][plane]; |
davidr99 | 0:9f43f6e0d6ad | 43 | |
davidr99 | 0:9f43f6e0d6ad | 44 | R1 = (val & 1); // Red bit, upper half |
davidr99 | 0:9f43f6e0d6ad | 45 | G1 = (val & 2); // Green bit, upper half |
davidr99 | 0:9f43f6e0d6ad | 46 | B1 = (val & 4); // Blue bit, upper half |
davidr99 | 0:9f43f6e0d6ad | 47 | |
davidr99 | 0:9f43f6e0d6ad | 48 | R2 = (val & 8); // Red bit, lower half |
davidr99 | 0:9f43f6e0d6ad | 49 | G2 = (val & 16); // Green bit, lower half |
davidr99 | 0:9f43f6e0d6ad | 50 | B2 = (val & 32); // Blue bit, lower half |
davidr99 | 0:9f43f6e0d6ad | 51 | CLK = HIGH; // tick (clock bit in) |
davidr99 | 0:9f43f6e0d6ad | 52 | CLK = LOW; // tock |
davidr99 | 0:9f43f6e0d6ad | 53 | } |
davidr99 | 0:9f43f6e0d6ad | 54 | LAT = HIGH; // Latch entire row |
davidr99 | 0:9f43f6e0d6ad | 55 | LAT = LOW; |
davidr99 | 0:9f43f6e0d6ad | 56 | } |
davidr99 | 0:9f43f6e0d6ad | 57 | |
davidr99 | 0:9f43f6e0d6ad | 58 | void Pset(unsigned char x,unsigned char y, unsigned long c) |
davidr99 | 0:9f43f6e0d6ad | 59 | { |
davidr99 | 0:9f43f6e0d6ad | 60 | int r, g, b; |
davidr99 | 0:9f43f6e0d6ad | 61 | |
davidr99 | 0:9f43f6e0d6ad | 62 | r = (c & 0xFF); // Extract red bit from color |
davidr99 | 0:9f43f6e0d6ad | 63 | g = (c & 0xFF00) >> 8; // Extract green bit from color |
davidr99 | 0:9f43f6e0d6ad | 64 | b = (c & 0xFF0000) >> 16; // Extract blue bit from color |
davidr99 | 0:9f43f6e0d6ad | 65 | |
davidr99 | 0:9f43f6e0d6ad | 66 | for(int p=0;p<nPlanes;p++) |
davidr99 | 0:9f43f6e0d6ad | 67 | { |
davidr99 | 0:9f43f6e0d6ad | 68 | if (y >= 16) |
davidr99 | 0:9f43f6e0d6ad | 69 | { |
davidr99 | 0:9f43f6e0d6ad | 70 | // Keep last 3 bits |
davidr99 | 0:9f43f6e0d6ad | 71 | gm[x][y - 16][p] = (gm[x][y - 16][p] & 0b111000) + ((r >> p) & 1) + (((g << 1) >> p) & 2) + (((b << 2) >> p) & 4); |
davidr99 | 0:9f43f6e0d6ad | 72 | } |
davidr99 | 0:9f43f6e0d6ad | 73 | else |
davidr99 | 0:9f43f6e0d6ad | 74 | { |
davidr99 | 0:9f43f6e0d6ad | 75 | // keep first 3 bits |
davidr99 | 0:9f43f6e0d6ad | 76 | gm[x][y][p] = (gm[x][y][p] & 0b000111) + ((((r >> p) & 1) + (((g << 1) >> p) & 2) + (((b << 2) >> p) & 4)) << 3); |
davidr99 | 0:9f43f6e0d6ad | 77 | } |
davidr99 | 0:9f43f6e0d6ad | 78 | } |
davidr99 | 0:9f43f6e0d6ad | 79 | } |
davidr99 | 0:9f43f6e0d6ad | 80 | |
davidr99 | 0:9f43f6e0d6ad | 81 | void Paint() |
davidr99 | 0:9f43f6e0d6ad | 82 | { |
davidr99 | 0:9f43f6e0d6ad | 83 | if (plane >= (nPlanes - 1)) |
davidr99 | 0:9f43f6e0d6ad | 84 | { |
davidr99 | 0:9f43f6e0d6ad | 85 | plane = 0; |
davidr99 | 0:9f43f6e0d6ad | 86 | } |
davidr99 | 0:9f43f6e0d6ad | 87 | else |
davidr99 | 0:9f43f6e0d6ad | 88 | { |
davidr99 | 0:9f43f6e0d6ad | 89 | plane++; |
davidr99 | 0:9f43f6e0d6ad | 90 | } |
davidr99 | 0:9f43f6e0d6ad | 91 | |
davidr99 | 0:9f43f6e0d6ad | 92 | // Write graphics memory to display |
davidr99 | 0:9f43f6e0d6ad | 93 | for(int Row=0; Row<16; Row++) { |
davidr99 | 0:9f43f6e0d6ad | 94 | OE = HIGH; // Disable output |
davidr99 | 0:9f43f6e0d6ad | 95 | WrRow(Row); |
davidr99 | 0:9f43f6e0d6ad | 96 | OE = LOW; // Enable output |
davidr99 | 0:9f43f6e0d6ad | 97 | wait_us(2 * (1 << plane)); // Wasting some time. Use for whatever else. Probably better with a ticker for the display refresh. |
davidr99 | 0:9f43f6e0d6ad | 98 | } |
davidr99 | 0:9f43f6e0d6ad | 99 | OE = HIGH; // Disable output |
davidr99 | 0:9f43f6e0d6ad | 100 | } |
davidr99 | 0:9f43f6e0d6ad | 101 | |
davidr99 | 0:9f43f6e0d6ad | 102 | void PaintThread() |
davidr99 | 0:9f43f6e0d6ad | 103 | { |
davidr99 | 0:9f43f6e0d6ad | 104 | Paint(); |
davidr99 | 0:9f43f6e0d6ad | 105 | } |
davidr99 | 0:9f43f6e0d6ad | 106 | |
davidr99 | 0:9f43f6e0d6ad | 107 | int main() |
davidr99 | 0:9f43f6e0d6ad | 108 | { |
davidr99 | 0:9f43f6e0d6ad | 109 | Init(); // Set things up |
davidr99 | 0:9f43f6e0d6ad | 110 | Ticker ticker; |
davidr99 | 0:9f43f6e0d6ad | 111 | ticker.attach(PaintThread, 0.003); |
davidr99 | 0:9f43f6e0d6ad | 112 | |
davidr99 | 0:9f43f6e0d6ad | 113 | while(1) { |
davidr99 | 0:9f43f6e0d6ad | 114 | |
davidr99 | 0:9f43f6e0d6ad | 115 | for(int x=0;x<64;x++) |
davidr99 | 0:9f43f6e0d6ad | 116 | { |
davidr99 | 0:9f43f6e0d6ad | 117 | for(int y=0;y<32;y++) |
davidr99 | 0:9f43f6e0d6ad | 118 | { |
davidr99 | 0:9f43f6e0d6ad | 119 | Pset(x, y, 0xFF0101); |
davidr99 | 0:9f43f6e0d6ad | 120 | } |
davidr99 | 0:9f43f6e0d6ad | 121 | //Paint(); // Display refresh time sets loop duration. |
davidr99 | 0:9f43f6e0d6ad | 122 | } |
davidr99 | 0:9f43f6e0d6ad | 123 | |
davidr99 | 0:9f43f6e0d6ad | 124 | Thread::wait(1000); |
davidr99 | 0:9f43f6e0d6ad | 125 | |
davidr99 | 0:9f43f6e0d6ad | 126 | for(int c=0; c<16; c++) { |
davidr99 | 0:9f43f6e0d6ad | 127 | for(int x=c; x<(63-c); x++) {// Top side |
davidr99 | 0:9f43f6e0d6ad | 128 | Pset(x,c,c); |
davidr99 | 0:9f43f6e0d6ad | 129 | Thread::wait(10); |
davidr99 | 0:9f43f6e0d6ad | 130 | //Paint(); // Display refresh time sets loop duration. |
davidr99 | 0:9f43f6e0d6ad | 131 | } |
davidr99 | 0:9f43f6e0d6ad | 132 | for(int y=c; y<(31-c); y++) {// Right side |
davidr99 | 0:9f43f6e0d6ad | 133 | Pset(63-c,y,c << 8); |
davidr99 | 0:9f43f6e0d6ad | 134 | Thread::wait(10); |
davidr99 | 0:9f43f6e0d6ad | 135 | //Paint(); |
davidr99 | 0:9f43f6e0d6ad | 136 | } |
davidr99 | 0:9f43f6e0d6ad | 137 | for(int x=(63-c); x>=c; x--) {// Bottom side |
davidr99 | 0:9f43f6e0d6ad | 138 | Pset(x,(31-c),c << 16); |
davidr99 | 0:9f43f6e0d6ad | 139 | Thread::wait(10); |
davidr99 | 0:9f43f6e0d6ad | 140 | //Paint(); |
davidr99 | 0:9f43f6e0d6ad | 141 | } |
davidr99 | 0:9f43f6e0d6ad | 142 | for(int y=(31-c); y>=c; y--) { // Left side |
davidr99 | 0:9f43f6e0d6ad | 143 | Pset(c,y,c << 8); |
davidr99 | 0:9f43f6e0d6ad | 144 | Thread::wait(10); |
davidr99 | 0:9f43f6e0d6ad | 145 | //Paint(); |
davidr99 | 0:9f43f6e0d6ad | 146 | } |
davidr99 | 0:9f43f6e0d6ad | 147 | } |
davidr99 | 0:9f43f6e0d6ad | 148 | |
davidr99 | 0:9f43f6e0d6ad | 149 | Thread::wait(1000); |
davidr99 | 0:9f43f6e0d6ad | 150 | |
davidr99 | 0:9f43f6e0d6ad | 151 | /* |
davidr99 | 0:9f43f6e0d6ad | 152 | for(long w=0;w<1000;w++) |
davidr99 | 0:9f43f6e0d6ad | 153 | { |
davidr99 | 0:9f43f6e0d6ad | 154 | Paint(); // Display refresh time sets loop duration. |
davidr99 | 0:9f43f6e0d6ad | 155 | }*/ |
davidr99 | 0:9f43f6e0d6ad | 156 | } |
davidr99 | 0:9f43f6e0d6ad | 157 | } |