/* * Copyright (c) 2021 Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * 4.0" TFT ST7796 with Touch Screen and SD Card Demo - DIRECT DRIVER TEST */ #include "pico/stdlib.h" #include "pico/binary_info.h" #include "board_config.h" // Board-specific pin configuration #include "sd_card.h" #include #include #include #include "display/low_level_render.h" #include "display/low_level_gui.h" #include "display/low_level_display.h" #include "lib/ft6336u/ft6336u.h" // Direct driver instead of abstraction // Binary info for RP2350 - ensures proper boot image structure bi_decl(bi_program_description("4.0\" TFT ST7796 with Touch and SD Card Demo")); bi_decl(bi_program_version_string("0.1")); bi_decl(bi_program_build_date_string(__DATE__)); // Screen dimensions and configuration from board_config.h const int V_WIDTH = DISPLAY_WIDTH; const int V_HEIGHT = DISPLAY_HEIGHT; // Touch indicator settings #define TOUCH_RADIUS 10 uint8_t bit_buffer[V_WIDTH * V_HEIGHT / 8]; /** * @brief Refresh the screen with the 1-bit buffer * * Displays work directly with 1-bit monochrome buffers. * The display driver internally converts to its native format (RGB565, etc.) * * @param buffer Pointer to 1-bit framebuffer (width*height/8 bytes) * @param display Pointer to display abstraction layer */ void refresh_screen(const uint8_t *buffer, LowLevelDisplay* display) { display->draw_buffer(buffer); display->refresh(); } int main() { // Initialize standard I/O for debugging with timeout // This prevents hanging when USB is not connected stdio_init_all(); sleep_ms(5000); // Wait for USB connection (if present) printf("\n=== %s Demo ===\n", BOARD_NAME); // Create display abstraction using factory method // The factory handles all board-specific configuration internally LowLevelDisplay* display = LowLevelDisplay::create((DisplayType)DISPLAY_TYPE_SELECTED, V_WIDTH, V_HEIGHT); if (!display) { printf("Failed to create display!\n"); return -1; } printf("Initializing 4.0\" TFT with Touch and SD Card...\n"); // Initialize the display if (!display->init()) { printf("Display initialization failed!\n"); delete display; return -1; } display->clear(false); // Clear to black LowLevelRenderer renderer(bit_buffer, V_WIDTH, V_HEIGHT); renderer.set_font(&font_5x5_obj); LowLevelGUI gui = LowLevelGUI(&renderer, font_BMplain_obj); LowLevelWindow *w1 = gui.draw_new_window(15, 15, V_WIDTH - 30, V_HEIGHT - 30, "Main Window"); gui.draw_status_bar(w1, 10, 40, 200, "PANELS", "Weekly Average Charge", 65, "190KWH"); gui.draw_circular_gauge(w1, 10, 100 - 10, 200, "SYSTEM EFF.", 68); // Refresh the screen with the rendered GUI refresh_screen(bit_buffer, display); // Initialize touch screen using DIRECT DRIVER (bypassing abstraction) printf("\n=== Direct FT6336U Touch Driver Test ===\n"); ft6336u_config_t touch_config = { .i2c = i2c1, .gpio_sda = 2, .gpio_scl = 3, .gpio_rst = 28, .gpio_int = 25, .screen_width = V_WIDTH, .screen_height = V_HEIGHT, .swap_xy = true, .invert_x = true, .invert_y = false }; printf("Touch Config:\n"); printf(" I2C: i2c1, SDA: 2, SCL: 3\n"); printf(" RST: 28, INT: 25\n"); printf(" Screen: %dx%d\n", V_WIDTH, V_HEIGHT); printf(" Transforms: swap_xy=%d, invert_x=%d, invert_y=%d\n\n", touch_config.swap_xy, touch_config.invert_x, touch_config.invert_y); fflush(stdout); bool touch_ok = ft6336u_init(&touch_config); if (touch_ok) { printf("Touch initialized successfully!\n"); printf("Chip ID: 0x%02X, FW Version: 0x%02X\n\n", ft6336u_get_chip_id(), ft6336u_get_firmware_version()); // Run communication test printf("Running I2C communication test...\n"); ft6336u_test_i2c(); printf("\n"); } else { printf("Touch initialization FAILED!\n\n"); } // Test SD card and FatFS if (sd_card_init_with_board_config()) { sd_card_test_fatfs(); } else { printf("SD Card initialization failed or no card present\n"); } printf("\n=== Entering Touch Test Loop ===\n"); printf("Touch the screen to see coordinates...\n\n"); fflush(stdout); // Main loop - handle touch events with direct driver int last_x = -1, last_y = -1; // Touch debouncing uint32_t last_touch_time = 0; const uint32_t debounce_ms = 20; bool was_touched = false; int touch_fail_count = 0; int touch_success_count = 0; while (1) { uint32_t now = to_ms_since_boot(get_absolute_time()); if (now - last_touch_time < debounce_ms) { sleep_ms(1); continue; } bool is_touched = touch_ok && ft6336u_is_touched(); if (is_touched) { ft6336u_touch_data_t touch_data; if (ft6336u_read_touch(&touch_data)) { touch_success_count++; if (touch_data.touch_count > 0) { int16_t x = touch_data.points[0].x; int16_t y = touch_data.points[0].y; printf("Touch: X=%d, Y=%d, Event=%d [Success: %d, Fail: %d]\n", x, y, touch_data.points[0].event, touch_success_count, touch_fail_count); fflush(stdout); last_x = x; last_y = y; was_touched = true; last_touch_time = now; } } else { touch_fail_count++; if (touch_fail_count % 10 == 0) { printf("Touch read failed (count: %d)\n", touch_fail_count); fflush(stdout); } } } else { if (was_touched) { last_x = -1; last_y = -1; was_touched = false; } } sleep_ms(5); } return 0; }