diff --git a/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp b/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp index 2e08af0..fa02d6d 100644 --- a/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp +++ b/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp @@ -587,88 +587,6 @@ void MatrixPanel_I2S_DMA::updateMatrixDMABuffer(uint8_t red, uint8_t green, uint } // colour depth loop (8) } // updateMatrixDMABuffer (full frame paint) - -#define CLK_PULSE digitalWrite(_cfg.gpio.clk, HIGH); digitalWrite(_cfg.gpio.clk, LOW); - -/** - * pre-init procedures for specific drivers - * - */ -void MatrixPanel_I2S_DMA::shiftDriver(const HUB75_I2S_CFG& _cfg){ - switch (_cfg.driver){ - case HUB75_I2S_CFG::ICN2038S: - case HUB75_I2S_CFG::FM6124: - case HUB75_I2S_CFG::FM6126A: - { - #if SERIAL_DEBUG - Serial.println( F("MatrixPanel_I2S_DMA - initializing FM6124 driver...")); - #endif - bool REG1[16] = {0,0,0,0,0, 1,1,1,1,1,1, 0,0,0,0,0}; // this sets global matrix brightness power - bool REG2[16] = {0,0,0,0,0, 0,0,0,0,1,0, 0,0,0,0,0}; // a single bit enables the matrix output - - for (uint8_t _pin:{_cfg.gpio.r1, _cfg.gpio.r2, _cfg.gpio.g1, _cfg.gpio.g2, _cfg.gpio.b1, _cfg.gpio.b2, _cfg.gpio.clk, _cfg.gpio.lat, _cfg.gpio.oe}){ - pinMode(_pin, OUTPUT); - digitalWrite(_pin, LOW); - } - - digitalWrite(_cfg.gpio.oe, HIGH); // Disable Display - - // Send Data to control register REG1 - // this sets the matrix brightness actually - for (int l = 0; l < PIXELS_PER_ROW; l++){ - for (uint8_t _pin:{_cfg.gpio.r1, _cfg.gpio.r2, _cfg.gpio.g1, _cfg.gpio.g2, _cfg.gpio.b1, _cfg.gpio.b2}) - digitalWrite(_pin, REG1[l%16]); // we have 16 bits shifters and write the same value all over the matrix array - - if (l > PIXELS_PER_ROW - 12){ // pull the latch 11 clocks before the end of matrix so that REG1 starts counting to save the value - digitalWrite(_cfg.gpio.lat, HIGH); - } - CLK_PULSE - } - - // drop the latch and save data to the REG1 all over the FM6124 chips - digitalWrite(_cfg.gpio.lat, LOW); - - // Send Data to control register REG2 (enable LED output) - for (int l = 0; l < PIXELS_PER_ROW; l++){ - for (uint8_t _pin:{_cfg.gpio.r1, _cfg.gpio.r2, _cfg.gpio.g1, _cfg.gpio.g2, _cfg.gpio.b1, _cfg.gpio.b2}) - digitalWrite(_pin, REG2[l%16]); // we have 16 bits shifters and we write the same value all over the matrix array - - if (l > PIXELS_PER_ROW - 13){ // pull the latch 12 clocks before the end of matrix so that reg2 stars counting to save the value - digitalWrite(_cfg.gpio.lat, HIGH); - } - CLK_PULSE - } - - // drop the latch and save data to the REG1 all over the FM6126 chips - digitalWrite(_cfg.gpio.lat, LOW); - - // blank data regs to keep matrix clear after manipulations - for (uint8_t _pin:{_cfg.gpio.r1, _cfg.gpio.r2, _cfg.gpio.g1, _cfg.gpio.g2, _cfg.gpio.b1, _cfg.gpio.b2}) - digitalWrite(_pin, LOW); - - for (int l = 0; l < PIXELS_PER_ROW; ++l){ - CLK_PULSE - } - - digitalWrite(_cfg.gpio.lat, HIGH); - CLK_PULSE - digitalWrite(_cfg.gpio.lat, LOW); - digitalWrite(_cfg.gpio.oe, LOW); // Enable Display - CLK_PULSE - } - break; - case HUB75_I2S_CFG::MBI5124: - /* MBI5124 chips must be clocked with positive-edge, since it's LAT signal - * resets on clock's rising edge while high - * https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/files/5952216/5a542453754da.pdf - */ - m_cfg.clkphase=true; - case HUB75_I2S_CFG::SHIFT: - default: - break; - } -} - /** * clear screen to black and reset all service bits */ diff --git a/ESP32-HUB75-MatrixPanel-I2S-DMA.h b/ESP32-HUB75-MatrixPanel-I2S-DMA.h index 81cfd95..8075051 100644 --- a/ESP32-HUB75-MatrixPanel-I2S-DMA.h +++ b/ESP32-HUB75-MatrixPanel-I2S-DMA.h @@ -227,7 +227,7 @@ struct HUB75_I2S_CFG { * Enumeration of hardware-specific chips * used to drive matrix modules */ - enum shift_driver {SHIFT=0, FM6124, FM6126A, ICN2038S, MBI5124}; + enum shift_driver {SHIFTREG=0, FM6124, FM6126A, ICN2038S, MBI5124}; /** * I2S clock speed selector @@ -282,7 +282,7 @@ struct HUB75_I2S_CFG { R1_PIN_DEFAULT, G1_PIN_DEFAULT, B1_PIN_DEFAULT, R2_PIN_DEFAULT, G2_PIN_DEFAULT, B2_PIN_DEFAULT, A_PIN_DEFAULT, B_PIN_DEFAULT, C_PIN_DEFAULT, D_PIN_DEFAULT, E_PIN_DEFAULT, LAT_PIN_DEFAULT, OE_PIN_DEFAULT, CLK_PIN_DEFAULT }, - shift_driver _drv = SHIFT, + shift_driver _drv = SHIFTREG, bool _dbuff = false, clk_speed _i2sspeed = HZ_10M, uint16_t _latblk = 1, @@ -641,6 +641,11 @@ class MatrixPanel_I2S_DMA { */ void shiftDriver(const HUB75_I2S_CFG& opts); + /** + * @brief - FM6124-family chips initialization routine + */ + void fm6124init(const HUB75_I2S_CFG& _cfg); + /** * @brief - reset OE bits in DMA buffer in a way to control brightness * @param brt - brightness level from 0 to row_width diff --git a/ESP32-HUB75-MatrixPanel-leddrivers.cpp b/ESP32-HUB75-MatrixPanel-leddrivers.cpp new file mode 100644 index 0000000..bb482a2 --- /dev/null +++ b/ESP32-HUB75-MatrixPanel-leddrivers.cpp @@ -0,0 +1,94 @@ +/* + Various LED Driver chips might need some specific code for initialisation/control logic + +*/ + +#include +#include "ESP32-HUB75-MatrixPanel-I2S-DMA.h" + +#define CLK_PULSE digitalWrite(_cfg.gpio.clk, HIGH); digitalWrite(_cfg.gpio.clk, LOW); + +/** + * @brief - pre-init procedures for specific led-drivers + * this method is called before DMA/I2S setup while GPIOs + * aint yet assigned for DMA operation + * + */ +void MatrixPanel_I2S_DMA::shiftDriver(const HUB75_I2S_CFG& _cfg){ + switch (_cfg.driver){ + case HUB75_I2S_CFG::ICN2038S: + case HUB75_I2S_CFG::FM6124: + case HUB75_I2S_CFG::FM6126A: + fm6124init(_cfg); + break; + case HUB75_I2S_CFG::MBI5124: + /* MBI5124 chips must be clocked with positive-edge, since it's LAT signal + * resets on clock's rising edge while high + * https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/files/5952216/5a542453754da.pdf + */ + m_cfg.clkphase=true; + break; + case HUB75_I2S_CFG::SHIFTREG: + default: + break; + } +} + + +void MatrixPanel_I2S_DMA::fm6124init(const HUB75_I2S_CFG& _cfg){ + #if SERIAL_DEBUG + Serial.println( F("MatrixPanel_I2S_DMA - initializing FM6124 driver...")); + #endif + bool REG1[16] = {0,0,0,0,0, 1,1,1,1,1,1, 0,0,0,0,0}; // this sets global matrix brightness power + bool REG2[16] = {0,0,0,0,0, 0,0,0,0,1,0, 0,0,0,0,0}; // a single bit enables the matrix output + + for (uint8_t _pin:{_cfg.gpio.r1, _cfg.gpio.r2, _cfg.gpio.g1, _cfg.gpio.g2, _cfg.gpio.b1, _cfg.gpio.b2, _cfg.gpio.clk, _cfg.gpio.lat, _cfg.gpio.oe}){ + pinMode(_pin, OUTPUT); + digitalWrite(_pin, LOW); + } + + digitalWrite(_cfg.gpio.oe, HIGH); // Disable Display + + // Send Data to control register REG1 + // this sets the matrix brightness actually + for (int l = 0; l < PIXELS_PER_ROW; l++){ + for (uint8_t _pin:{_cfg.gpio.r1, _cfg.gpio.r2, _cfg.gpio.g1, _cfg.gpio.g2, _cfg.gpio.b1, _cfg.gpio.b2}) + digitalWrite(_pin, REG1[l%16]); // we have 16 bits shifters and write the same value all over the matrix array + + if (l > PIXELS_PER_ROW - 12){ // pull the latch 11 clocks before the end of matrix so that REG1 starts counting to save the value + digitalWrite(_cfg.gpio.lat, HIGH); + } + CLK_PULSE + } + + // drop the latch and save data to the REG1 all over the FM6124 chips + digitalWrite(_cfg.gpio.lat, LOW); + + // Send Data to control register REG2 (enable LED output) + for (int l = 0; l < PIXELS_PER_ROW; l++){ + for (uint8_t _pin:{_cfg.gpio.r1, _cfg.gpio.r2, _cfg.gpio.g1, _cfg.gpio.g2, _cfg.gpio.b1, _cfg.gpio.b2}) + digitalWrite(_pin, REG2[l%16]); // we have 16 bits shifters and we write the same value all over the matrix array + + if (l > PIXELS_PER_ROW - 13){ // pull the latch 12 clocks before the end of matrix so that reg2 stars counting to save the value + digitalWrite(_cfg.gpio.lat, HIGH); + } + CLK_PULSE + } + + // drop the latch and save data to the REG1 all over the FM6126 chips + digitalWrite(_cfg.gpio.lat, LOW); + + // blank data regs to keep matrix clear after manipulations + for (uint8_t _pin:{_cfg.gpio.r1, _cfg.gpio.r2, _cfg.gpio.g1, _cfg.gpio.g2, _cfg.gpio.b1, _cfg.gpio.b2}) + digitalWrite(_pin, LOW); + + for (int l = 0; l < PIXELS_PER_ROW; ++l){ + CLK_PULSE + } + + digitalWrite(_cfg.gpio.lat, HIGH); + CLK_PULSE + digitalWrite(_cfg.gpio.lat, LOW); + digitalWrite(_cfg.gpio.oe, LOW); // Enable Display + CLK_PULSE +} \ No newline at end of file