diff --git a/CMakeLists.txt b/CMakeLists.txt index 39da738..92543c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,12 +39,25 @@ if (TARGET tinyusb_device) add_executable(hello_usb hello_usb.cpp display.cpp + commands/echo.cpp ) - add_subdirectory(pico-ssd1306) + add_subdirectory(pico-ssd1306 commands) + add_subdirectory(Pico_ePaper_Code/c/lib/Config) + add_subdirectory(Pico_ePaper_Code/c/lib/e-Paper) + add_subdirectory(Pico_ePaper_Code/c/lib/Fonts) + add_subdirectory(Pico_ePaper_Code/c/lib/GUI) + + # Add include directories for e-Paper + target_include_directories(hello_usb PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/Pico_ePaper_Code/c/lib/Config + ${CMAKE_CURRENT_SOURCE_DIR}/Pico_ePaper_Code/c/lib/e-Paper + ${CMAKE_CURRENT_SOURCE_DIR}/Pico_ePaper_Code/c/lib/Fonts + ${CMAKE_CURRENT_SOURCE_DIR}/Pico_ePaper_Code/c/lib/GUI + ) # pull in common dependencies - target_link_libraries(hello_usb pico_stdlib pico_ssd1306 hardware_i2c) + target_link_libraries(hello_usb pico_stdlib pico_ssd1306 hardware_i2c Config ePaper GUI Fonts hardware_spi) # enable usb output, disable uart output pico_enable_stdio_usb(hello_usb 1) diff --git a/Pico_ePaper_Code b/Pico_ePaper_Code new file mode 160000 index 0000000..c9bcd84 --- /dev/null +++ b/Pico_ePaper_Code @@ -0,0 +1 @@ +Subproject commit c9bcd84db5adf5f085353649a8a5c31492bc5fb8 diff --git a/commands/echo.cpp b/commands/echo.cpp new file mode 100644 index 0000000..01d26aa --- /dev/null +++ b/commands/echo.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +#include "echo.h" + +// Helper function to handle the echoing and resetting of the buffer +void echo_and_reset(char* buffer, int* index_ptr) { + if (*index_ptr > 0) { + buffer[*index_ptr] = '\0'; + // Print to USB serial (ALL CAPS) + printf("\nEchoed (ALL CAPS): "); + for (int i = 0; buffer[i] != '\0'; i++) { + char ch = toupper(buffer[i]); + printf("%c", ch); + } + printf("\n"); + } + + *index_ptr = 0; + printf("> "); +} \ No newline at end of file diff --git a/commands/echo.h b/commands/echo.h new file mode 100644 index 0000000..697b98b --- /dev/null +++ b/commands/echo.h @@ -0,0 +1,14 @@ +#ifndef COMMANDS_ECHO_H +#define COMMANDS_ECHO_H + +#ifdef __cplusplus +extern "C" { +#endif + +void echo_and_reset(char* buffer, int* index_ptr); + +#ifdef __cplusplus +} +#endif + +#endif // COMMANDS_ECHO_H \ No newline at end of file diff --git a/hello_usb.cpp b/hello_usb.cpp index 626ca0a..b6d76f6 100644 --- a/hello_usb.cpp +++ b/hello_usb.cpp @@ -1,6 +1,7 @@ /* * Simple USB Serial Echo Program with Timeout, Reconnect, and Backspace Logic. * Converted to C++ so the project can use the `pico-ssd1306` C++ library. + * Integrated with e-ink display support via Pico_ePaper library. */ #include "pico/stdlib.h" @@ -8,12 +9,101 @@ #include #include #include +#include #include "display.h" +#include "commands/echo.h" + +// e-Paper library includes +extern "C" { + #include "DEV_Config.h" + #include "EPD_7in5b_V2.h" + #include "GUI_Paint.h" +} // Holds last echoed line for display static char g_last_echo[128] = ""; +// e-Paper display buffers +static UBYTE *g_epd_image = NULL; // Black image buffer +static UBYTE *g_epd_red = NULL; // Red image buffer + +void init_epaper_display() { + printf("Initializing 7.5\" e-Paper display (B V2)...\r\n"); + + // Initialize the hardware + if (DEV_Module_Init() != 0) { + printf("Failed to initialize e-Paper hardware!\r\n"); + return; + } + + // Initialize the display + printf("EPD_7IN5B_V2_Init()\r\n"); + EPD_7IN5B_V2_Init_Fast(); + printf("EPD_7IN5B_V2_Clear()\r\n"); + EPD_7IN5B_V2_ClearBlack(); + DEV_Delay_ms(500); + + // Create image buffers for black and red content + // 7.5" display: 800x480, 8 pixels per byte, so (800/8) * 480 = 48000 bytes each + UWORD imagesize = (EPD_7IN5B_V2_WIDTH / 8) * EPD_7IN5B_V2_HEIGHT; + + g_epd_image = (UBYTE *)malloc(imagesize); + g_epd_red = (UBYTE *)malloc(imagesize); + + if (g_epd_image == NULL || g_epd_red == NULL) { + printf("Failed to allocate memory for e-Paper image buffers!\r\n"); + return; + } + + // Initialize red buffer to all white (0xFF = no red pixels) + for (UWORD i = 0; i < imagesize; i++) { + g_epd_red[i] = 0xFF; + } + + // Setup paint buffer for black content + printf("White background\r\n"); + Paint_NewImage(g_epd_image, EPD_7IN5B_V2_WIDTH, EPD_7IN5B_V2_HEIGHT, 0, WHITE); + Paint_SelectImage(g_epd_image); + Paint_Clear(WHITE); + + // Draw "Hello World" on the display + printf("Drawing\r\n"); + Paint_DrawString_EN(10, 10, "Hello World!", &Font24, WHITE, BLACK); + Paint_DrawString_EN(10, 60, "7.5\" e-Paper Initialized", &Font16, WHITE, BLACK); + + // Display the image with both black and red buffers + printf("display text\r\n"); + EPD_7IN5B_V2_Display(g_epd_image, g_epd_red); + printf("delay\r\n"); + DEV_Delay_ms(2000); + + printf("e-Paper display ready!\r\n"); + // EPD_7IN5B_V2_Sleep(); +} + +void update_epaper_display(const char *line1, const char *line2) { + if (g_epd_image == NULL || g_epd_red == NULL) return; + + // Clear and prepare buffers + UWORD imagesize = (EPD_7IN5B_V2_WIDTH / 8) * EPD_7IN5B_V2_HEIGHT; + for (UWORD i = 0; i < imagesize; i++) { + g_epd_red[i] = 0xFF; // No red pixels + } + + Paint_SelectImage(g_epd_image); + Paint_Clear(WHITE); + + if (line1) { + Paint_DrawString_EN(50, 100, (char *)line1, &Font16, BLACK, WHITE); + } + if (line2) { + Paint_DrawString_EN(50, 150, (char *)line2, &Font16, BLACK, WHITE); + } + + EPD_7IN5B_V2_Display(g_epd_image, g_epd_red); +} + // Define the maximum size for the input string buffer #define MAX_INPUT_LEN 64 // Define the timeout period: 5 seconds in microseconds @@ -21,55 +111,30 @@ static char g_last_echo[128] = ""; // ASCII code for Backspace (often sent as 0x08) #define ASCII_BACKSPACE 8 -// Helper function to handle the echoing and resetting of the buffer -void echo_and_reset(char* buffer, int* index_ptr, DisplayManager &display) { - if (*index_ptr > 0) { - buffer[*index_ptr] = '\0'; - // Print to USB serial (ALL CAPS) - printf("\nEchoed (ALL CAPS): "); - for (int i = 0; buffer[i] != '\0'; i++) { - char ch = toupper(buffer[i]); - printf("%c", ch); - } - printf("\n"); - - // Save last echoed (all caps) for display - size_t i = 0; - for (; buffer[i] != '\0' && i < sizeof(g_last_echo) - 1; ++i) { - g_last_echo[i] = (char)toupper(buffer[i]); - } - g_last_echo[i] = '\0'; - } - - *index_ptr = 0; - printf("> "); - // Update OLED to show cleared input and last echo - display.set_last_echo(g_last_echo); - display.refresh("", g_last_echo); -} - -void wait_for_usb_connection() { +void wait_for_usb_connection(DisplayManager &display) { printf("Waiting for USB host to connect...\n"); while (!stdio_usb_connected()) { sleep_ms(100); } printf("\nConnection Established! Starting Echo Session...\n"); + display.refresh(">", nullptr); + + // Initialize e-Paper display + init_epaper_display(); } void run_echo_session(DisplayManager &display) { char input_buffer[MAX_INPUT_LEN]; int buffer_index = 0; - uint64_t last_char_time = time_us_64(); - printf("--- Pico USB String Echo Program Started ---\n"); - printf("Type a sentence (up to %d chars). It will echo on Enter/Timeout.\n", MAX_INPUT_LEN - 2); + printf("--- Welcome User! ---\n"); + printf("Type a command (or write help):\n"); printf("--------------------------------------------\n"); printf("> "); while (stdio_usb_connected()) { int c = getchar_timeout_us(0); if (c != PICO_ERROR_TIMEOUT) { - last_char_time = time_us_64(); char input_char = (char)c; if (input_char == ASCII_BACKSPACE || input_char == 127) { if (buffer_index > 0) { @@ -80,8 +145,16 @@ void run_echo_session(DisplayManager &display) { display.refresh(input_buffer, g_last_echo); } } else if (input_char == '\r' || input_char == '\n') { - echo_and_reset(input_buffer, &buffer_index, display); - // after echo_and_reset the display is refreshed inside it + echo_and_reset(input_buffer, &buffer_index); + // Save last echoed (all caps) for display + size_t i = 0; + for (; input_buffer[i] != '\0' && i < sizeof(g_last_echo) - 1; ++i) { + g_last_echo[i] = input_buffer[i]; + } + g_last_echo[i] = '\0'; + // Update OLED to show cleared input and last echo + display.set_last_echo(g_last_echo); + display.refresh("", g_last_echo); } else if (buffer_index < (MAX_INPUT_LEN - 1) && isprint(input_char)) { printf("%c", input_char); input_buffer[buffer_index] = input_char; @@ -91,29 +164,22 @@ void run_echo_session(DisplayManager &display) { display.refresh(input_buffer, g_last_echo); } } - - if (buffer_index > 0 && (time_us_64() - last_char_time) > TIMEOUT_US) { - printf("\n--- Timeout Reached (5.0s silence) ---\n"); - echo_and_reset(input_buffer, &buffer_index, display); - last_char_time = time_us_64(); - } - - // Advance marquee for last echoed text if needed - size_t last_len = strlen(g_last_echo); - uint64_t now_ms = time_us_64() / 1000; sleep_us(100); } - + printf("\nHost disconnected. Ending Echo Session.\n"); } int main() { stdio_init_all(); + + DisplayManager display; display.init(); + display.refresh("Waiting for USB/Serial", nullptr); while (true) { - wait_for_usb_connection(); + wait_for_usb_connection(display); run_echo_session(display); }