diff --git a/dreader/hal_hardware.py b/dreader/hal_hardware.py index 99dbd0b..6241356 100644 --- a/dreader/hal_hardware.py +++ b/dreader/hal_hardware.py @@ -140,6 +140,7 @@ class HardwareDisplayHAL(DisplayHAL): height: int = 1404, vcom: float = -2.0, spi_hz: int = 24_000_000, + rotate: Optional[str] = None, virtual_display: bool = False, auto_sleep_display: bool = True, enable_orientation: bool = True, @@ -170,8 +171,29 @@ class HardwareDisplayHAL(DisplayHAL): self.width = width self.height = height + # Load config from file to get display settings + full_config = None + if config_file or gpio_config is None: + config_path = Path(config_file or "hardware_config.json") + if config_path.exists(): + try: + with open(config_path, 'r') as f: + full_config = json.load(f) + logger.info(f"Loaded hardware config from {config_path}") + + # Override display parameters from config if not explicitly provided + display_config = full_config.get('display', {}) + if rotate is None and 'rotate' in display_config: + rotate = display_config['rotate'] + logger.info(f" Using rotate from config: {rotate}") + + gpio_config = full_config + except Exception as e: + logger.warning(f"Could not load hardware config from {config_path}: {e}") + logger.info(f"Initializing HardwareDisplayHAL: {width}x{height}") logger.info(f" VCOM: {vcom}V") + logger.info(f" Rotate: {rotate}") logger.info(f" Virtual display: {virtual_display}") logger.info(f" Orientation: {enable_orientation}") logger.info(f" RTC: {enable_rtc}") @@ -183,6 +205,7 @@ class HardwareDisplayHAL(DisplayHAL): height=height, vcom=vcom, spi_hz=spi_hz, + rotate=rotate, virtual_display=virtual_display, auto_sleep_display=auto_sleep_display, enable_orientation=enable_orientation, @@ -195,18 +218,6 @@ class HardwareDisplayHAL(DisplayHAL): # GPIO button handler (optional) self.gpio_handler: Optional[GPIOButtonHandler] = None - # Load GPIO config from file if specified - if config_file or gpio_config is None: - config_path = Path(config_file or "hardware_config.json") - if config_path.exists(): - try: - with open(config_path, 'r') as f: - full_config = json.load(f) - gpio_config = full_config - logger.info(f"Loaded hardware config from {config_path}") - except Exception as e: - logger.warning(f"Could not load hardware config from {config_path}: {e}") - # Initialize GPIO buttons if configured if gpio_config and GPIO_BUTTONS_AVAILABLE: try: diff --git a/examples/test_direct_it8951.py b/examples/test_direct_it8951.py new file mode 100755 index 0000000..91c0dbc --- /dev/null +++ b/examples/test_direct_it8951.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +""" +Direct IT8951 test - bypasses the HAL completely. +Uses IT8951 library directly like the working example. +""" + +from IT8951 import constants +from IT8951.display import AutoEPDDisplay +from PIL import Image + + +def main(): + """Test display with direct IT8951 access.""" + + print("=" * 60) + print("Direct IT8951 Test - Half Black, Half White") + print("=" * 60) + print() + print("This test bypasses the HAL and uses IT8951 directly.") + print("Matches the working code you provided.") + print() + + # Display size + width, height = 1872, 1404 + shape = (height, width) # IT8951 uses (height, width) format + + print(f"Display shape: {shape} (height, width)") + print(f"Dimensions: {width}x{height}") + print() + + # Create test image + print("Creating test image...") + print(" Left half: BLACK (0)") + print(" Right half: WHITE (255)") + + # Create grayscale image + screen = Image.new('L', shape, color=255) # White background + + # Draw left half black + pixels = screen.load() + for y in range(height): + for x in range(width // 2): + pixels[x, y] = 0 # Black + + print(f"✓ Image created: {screen.size} {screen.mode}") + print() + + # Save for reference + output_file = "direct_test.png" + screen.save(output_file) + print(f"✓ Saved to: {output_file}") + print() + + # Initialize display + print("Initializing IT8951 display...") + print(" VCOM: -1.7V") + print(" Rotation: CW (clockwise)") + print(" SPI: 24MHz") + + display = AutoEPDDisplay( + vcom=-1.7, + rotate="CW", + spi_hz=24000000, + device=0, + bus=0 + ) + + print("✓ Display initialized") + print() + + # Display the image + print("Displaying image...") + print(" Using frame_buf.paste() + draw_full(GC16)") + + display.frame_buf.paste(screen, (0, 0)) + display.draw_full(constants.DisplayModes.GC16) + + print("✓ Image displayed!") + print() + + print("=" * 60) + print("CHECK YOUR SCREEN:") + print("=" * 60) + print() + print("You should see:") + print(" • LEFT HALF: BLACK") + print(" • RIGHT HALF: WHITE") + print() + print("If this works, the display hardware is fine!") + print("If this doesn't work, there's a hardware/wiring issue.") + print() + + # Sleep display + input("Press Enter to put display to sleep and exit...") + + epd = display.epd + epd.sleep() + + print("Display put to sleep. Done!") + + +if __name__ == "__main__": + try: + main() + except KeyboardInterrupt: + print("\n\nTest interrupted") + except Exception as e: + print(f"\nERROR: {e}") + import traceback + traceback.print_exc() diff --git a/external/dreader-hal b/external/dreader-hal index bfa51c1..64c9177 160000 --- a/external/dreader-hal +++ b/external/dreader-hal @@ -1 +1 @@ -Subproject commit bfa51c1439301d778f57cae09679cb68695454ed +Subproject commit 64c91776045093a7a46538aa3899a1709c44568a