Tags: esphome-libs/esp-hub75
Tags
Fix low brightness color issues across all platforms (#66) * Fix BCM bitplane formula causing color distortion at low brightness The original bitplane formula `(2 * bit_depth_ - bit) % bit_depth_` produced incorrect mappings for 8-bit depth: - bit 0 (LSB) → bitplane 0 (long OE time) - WRONG - bit 1 → bitplane 7 (short OE time) - WRONG - bit 7 (MSB) → bitplane 1 (long OE time) - correct This caused bits 1-3 to have disproportionately short OE times at low brightness, resulting in muddy/reddish colors because the middle bits that differentiate hues were being suppressed. The fix uses `bit_depth_ - 1 - bit` which correctly maps: - bit 0 (LSB) → bitplane 7 → short OE time - bit 7 (MSB) → bitplane 0 → long OE time This ensures proper BCM weighting where MSB gets the longest display time and LSB gets the shortest. * Fix PARLIO brightness to use per-bit-plane BCM weighting PARLIO's calculate_bcm_padding gives bits 0-4 (for lsbMsbTransitionBit=3) the same padding size, but the brightness code was using uniform max_display for all bits. This meant bits 0-4 all had equal display time, breaking BCM ratios (should be 1:2:4:8:16, was 1:1:1:1:1). Apply the same rightshift-based BCM weighting as GDMA/I2S to achieve proper BCM ratios via OE duty cycle within the padding section. * Improve low brightness color fidelity with hybrid minimum approach Use a hybrid approach that gradually includes more bits for the minimum=1 floor as brightness increases: - brightness 1-15: only bit 7 (MSB) gets minimum=1 - brightness 16-31: bits 6-7 get minimum=1 - brightness 32-47: bits 5-7 get minimum=1 - ... and so on This ensures: 1. Screen is never blank at brightness > 0 (MSB always gets at least 1) 2. At very low brightness, only MSB is visible (no ratio distortion) 3. As brightness increases, more bits naturally exceed 0 anyway 4. Better color fidelity than clamping all bits to 1 Formula: min_bit = bit_depth - 1 - (brightness / 16) Applied to GDMA, I2S, and PARLIO platforms. * Revert PARLIO brightness changes (keep GDMA/I2S fixes) PARLIO uses padding-based BCM timing (not descriptor repetition like GDMA/I2S), so applying the rightshift formula would cause double BCM weighting and crush bits 1-2, causing color distortion. The GDMA/I2S bitplane formula fix and hybrid minimum algorithm are correct for those platforms. * Fix PARLIO low brightness with hybrid BCM approach PARLIO's BCM architecture requires different handling for LSB vs MSB bits: - Bits > lsbMsbTransitionBit: Have exponential padding sizes that provide BCM timing. No rightshift needed (would double-weight). - Bits <= lsbMsbTransitionBit: Have IDENTICAL padding sizes (all get base_padding + base_display). Need rightshift for BCM differentiation via OE duty cycle. Also adds hybrid minimum algorithm (matching GDMA/I2S) to preserve color ratios at low brightness instead of forcing all bits to display. * Add minimum brightness floor to maintain BCM ratios At low brightness (e.g., brightness=4), bits 2-7 all calculate to display_pixels=1, destroying BCM ratios that should be 1:2:4:8:16:32. Rather than accepting broken colors at low brightness, establish a minimum brightness floor of 32 where proper BCM ratios can be maintained. This gives ~4 bits of color resolution even at the lowest brightness. Applied to all three platforms: GDMA, I2S, and PARLIO. * Use smooth brightness remapping instead of clamp Instead of clamping brightness 1-31 to 32 (losing 31 levels), linearly remap the full 1-255 range to 32-255. This preserves all 255 brightness levels while ensuring proper BCM ratios. Formula: effective = 32 + (brightness * 223) / 255 - brightness=1 → effective=32 - brightness=128 → effective=144 - brightness=255 → effective=255 Intensity is still correctly applied (multiplied before this remapping). * Calculate minimum brightness dynamically based on panel width The minimum brightness needed for proper BCM ratios depends on dma_width: - 64-wide panel: min = 65 - 128-wide panel: min = 32 - 256-wide panel: min = 16 Formula: min_brightness = (16 * 256) / (dma_width - latch_blanking) This ensures 4-bit BCM ratio range (bits 4-7) regardless of panel size. User brightness 1-255 is linearly remapped to min_brightness-255. * Update comments * simplify * remove old brightness debugging code * Lower minimum brightness threshold from 16 to 8 Reduces the minimum brightness floor to allow more usable low-brightness range. New minimums by panel width: - 64-wide: 33 (was 65) - 128-wide: 16 (was 32) - 256-wide: 8 (was 16) Trade-off: 3-bit color depth at minimum (8:4:2 ratios) instead of 4-bit (16:8:4:2). Lower bits contribute minimally due to CIE correction anyway. * remove double bcm calc * Fix validation code error * clean up comments --------- Co-authored-by: Claude <noreply@anthropic.com>
Add support for 4-bit and 5-bit color depth (#42) Extends the minimum supported bit depth from 6-bit to 4-bit, enabling higher refresh rates on large panel arrays at the cost of reduced color gradation. Changes: - Update static_assert in color_lut.h to allow BitDepth >= 4 - Add DEPTH_4 and DEPTH_5 options to Kconfig with descriptive help text - Update documentation (COLOR_GAMMA.md, MENUCONFIG.md, README.md) with new bit depth options and use case guidance
PreviousNext