From 15eaa3e9d394252190eec44b42e555e98a7c4c57 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Fri, 19 Feb 2021 12:08:15 +0300 Subject: [PATCH] Clock phase toggling option, required to support MBI5124 chips Closes #75 Signed-off-by: Emil Muratov --- ESP32-HUB75-MatrixPanel-I2S-DMA.cpp | 9 ++++++++- ESP32-HUB75-MatrixPanel-I2S-DMA.h | 22 +++++++++++++++++++--- esp32_i2s_parallel_v2.c | 5 ++++- esp32_i2s_parallel_v2.h | 1 + 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp b/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp index 6525ef4..2e08af0 100644 --- a/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp +++ b/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp @@ -421,7 +421,8 @@ void MatrixPanel_I2S_DMA::configureDMA(const HUB75_I2S_CFG& _cfg) .desccount_a=desccount, .lldesc_a=dmadesc_a, .desccount_b=desccount, - .lldesc_b=dmadesc_b + .lldesc_b=dmadesc_b, + .clkphase=_cfg.clkphase }; // Setup I2S @@ -656,6 +657,12 @@ void MatrixPanel_I2S_DMA::shiftDriver(const HUB75_I2S_CFG& _cfg){ 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; diff --git a/ESP32-HUB75-MatrixPanel-I2S-DMA.h b/ESP32-HUB75-MatrixPanel-I2S-DMA.h index c17a08d..81cfd95 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}; + enum shift_driver {SHIFT=0, FM6124, FM6126A, ICN2038S, MBI5124}; /** * I2S clock speed selector @@ -258,6 +258,20 @@ struct HUB75_I2S_CFG { // How many clock cycles to blank OE before/after LAT signal change, default is 1 clock uint8_t latch_blanking; + /** + * I2S clock phase + * 0 (default) - data lines are clocked with negative edge + * Clk /¯\_/¯\_/ + * LAT __/¯¯¯\__ + * EO ¯¯¯¯¯¯\___ + * + * 1 - data lines are clocked with positive edge + * Clk \_/¯\_/¯\ + * LAT __/¯¯¯\__ + * EO ¯¯¯¯¯¯\__ + * + */ + bool clkphase; // struct constructor HUB75_I2S_CFG ( @@ -271,14 +285,16 @@ struct HUB75_I2S_CFG { shift_driver _drv = SHIFT, bool _dbuff = false, clk_speed _i2sspeed = HZ_10M, - uint16_t _latblk = 1 + uint16_t _latblk = 1, + bool _clockphase = false ) : mx_width(_w), mx_height(_h), chain_length(_chain), gpio(_pinmap), driver(_drv), i2sspeed(_i2sspeed), double_buff(_dbuff), - latch_blanking(_latblk) {} + latch_blanking(_latblk), + clkphase(_clockphase) {} }; // end of structure HUB75_I2S_CFG diff --git a/esp32_i2s_parallel_v2.c b/esp32_i2s_parallel_v2.c index ba88f10..966aaee 100644 --- a/esp32_i2s_parallel_v2.c +++ b/esp32_i2s_parallel_v2.c @@ -291,7 +291,10 @@ esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* co for(int i = 0; i < bus_width; i++) { iomux_set_signal(conf->gpio_bus[i], iomux_signal_base + i); } - iomux_set_signal(conf->gpio_clk, iomux_clock); + iomux_set_signal(conf->gpio_clk, iomux_clock); + // invert clock phase if required + if (conf->clkphase) + GPIO.func_out_sel_cfg[conf->gpio_clk].inv_sel = 1; return ESP_OK; } diff --git a/esp32_i2s_parallel_v2.h b/esp32_i2s_parallel_v2.h index 16b094d..d0c6749 100644 --- a/esp32_i2s_parallel_v2.h +++ b/esp32_i2s_parallel_v2.h @@ -41,6 +41,7 @@ typedef struct { lldesc_t * lldesc_a; int desccount_b; // only used with double buffering lldesc_t * lldesc_b; // only used with double buffering + bool clkphase; // Clock signal phase } i2s_parallel_config_t; static inline int i2s_parallel_get_memory_width(i2s_port_t port, i2s_parallel_cfg_bits_t width) {