Clock phase toggling option, required to support MBI5124 chips

Closes #75

Signed-off-by: Emil Muratov <gpm@hotplug.ru>
This commit is contained in:
Emil Muratov 2021-02-19 12:08:15 +03:00
parent 895bb80b43
commit 15eaa3e9d3
4 changed files with 32 additions and 5 deletions

View file

@ -421,7 +421,8 @@ void MatrixPanel_I2S_DMA::configureDMA(const HUB75_I2S_CFG& _cfg)
.desccount_a=desccount, .desccount_a=desccount,
.lldesc_a=dmadesc_a, .lldesc_a=dmadesc_a,
.desccount_b=desccount, .desccount_b=desccount,
.lldesc_b=dmadesc_b .lldesc_b=dmadesc_b,
.clkphase=_cfg.clkphase
}; };
// Setup I2S // Setup I2S
@ -656,6 +657,12 @@ void MatrixPanel_I2S_DMA::shiftDriver(const HUB75_I2S_CFG& _cfg){
CLK_PULSE CLK_PULSE
} }
break; 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: case HUB75_I2S_CFG::SHIFT:
default: default:
break; break;

View file

@ -227,7 +227,7 @@ struct HUB75_I2S_CFG {
* Enumeration of hardware-specific chips * Enumeration of hardware-specific chips
* used to drive matrix modules * 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 * 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 // How many clock cycles to blank OE before/after LAT signal change, default is 1 clock
uint8_t latch_blanking; 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 // struct constructor
HUB75_I2S_CFG ( HUB75_I2S_CFG (
@ -271,14 +285,16 @@ struct HUB75_I2S_CFG {
shift_driver _drv = SHIFT, shift_driver _drv = SHIFT,
bool _dbuff = false, bool _dbuff = false,
clk_speed _i2sspeed = HZ_10M, clk_speed _i2sspeed = HZ_10M,
uint16_t _latblk = 1 uint16_t _latblk = 1,
bool _clockphase = false
) : mx_width(_w), ) : mx_width(_w),
mx_height(_h), mx_height(_h),
chain_length(_chain), chain_length(_chain),
gpio(_pinmap), gpio(_pinmap),
driver(_drv), i2sspeed(_i2sspeed), driver(_drv), i2sspeed(_i2sspeed),
double_buff(_dbuff), double_buff(_dbuff),
latch_blanking(_latblk) {} latch_blanking(_latblk),
clkphase(_clockphase) {}
}; // end of structure HUB75_I2S_CFG }; // end of structure HUB75_I2S_CFG

View file

@ -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++) { for(int i = 0; i < bus_width; i++) {
iomux_set_signal(conf->gpio_bus[i], iomux_signal_base + 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; return ESP_OK;
} }

View file

@ -41,6 +41,7 @@ typedef struct {
lldesc_t * lldesc_a; lldesc_t * lldesc_a;
int desccount_b; // only used with double buffering int desccount_b; // only used with double buffering
lldesc_t * lldesc_b; // only used with double buffering lldesc_t * lldesc_b; // only used with double buffering
bool clkphase; // Clock signal phase
} i2s_parallel_config_t; } i2s_parallel_config_t;
static inline int i2s_parallel_get_memory_width(i2s_port_t port, i2s_parallel_cfg_bits_t width) { static inline int i2s_parallel_get_memory_width(i2s_port_t port, i2s_parallel_cfg_bits_t width) {