Adafruit Led Matrix 64x32 Lib
Dependents: Adafruit-64x32-PWM-Demo
Diff: LedMatrix.cpp
- 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